/ / Übergeben Sie den Namen und den Wert des Arguments innerhalb einer Funktion - r

Übergeben Sie den Argumentnamen und -wert innerhalb einer Funktion - r

Ich habe bereits einige Funktionen, die manipulierensowohl den Namen als auch andere Eigenschaften desselben Objekts. Während sie in Ordnung arbeiten, habe ich Schwierigkeiten, eine "Kontrolle" zu schreiben, die das Argument in einem Zug an alle weitergeben würde.

Bisher habe ich das Problem auf das Problem eingegrenztName des Arguments. Zur Verdeutlichung zeigt der vereinfachte Code unten, dass der Name nicht von der "Steuerung" (f2) an die einzelnen Funktionen (f1) weitergegeben wurde.

x=7
f1<-function(a){
label<-deparse(substitute(a))
cat("f1 value:",a,"n")
cat("f1 label:",label,"n")
}

f2<-function(b){
label<-deparse(substitute(b))
cat("f2 value:",b,"n")
cat("f2 label:",label,"n")
f1(b)
}
f2(x)


#>f2 value: 7
#>f2 label: x
#>f1 value: 7
#>f1 label: b

Es scheint, dass das Objekt x ordnungsgemäß übergeben wurdeauf f2, wie der zurückgegebene Wert 7 und der Name "x" anzeigen. Beim Aufruf von f1 innerhalb von f2 konnte ich nur den Wert des Objekts x weitergeben, nicht den Namen. Korrigieren Sie mich, wenn ich falsch liege. Mein Verständnis ist jedoch, dass f1 nur die Bindung zwischen dem Namen "b" und dem Wert 7 durch das Argument sieht.

Gibt es eine Möglichkeit, f1 sowohl den Namen lesen zu lassenund Wert von "x" in diesem Beispiel? Ich bin ziemlich neu in R und habe versucht, mein halbwegs gebranntes Verständnis von Umgebungen, Bewertung und Aufrufen ohne Erfolg anzuwenden. Die einzige Lösung, die ich gefunden habe, ist die Verwendung von "label" als global in f2 bis << -, was alles andere als ideal ist.

Vielen Dank im Voraus für jede Eingabe.

Editiert: der vollständige korrigierte Code

Danke an die Vorschläge von MrFlick. Hier ist der Code für das eigentliche Problem, das ich lösen wollte (jetzt behoben). Da ich neu bei R bin, würde ich mich über Vorschläge für bessere Möglichkeiten freuen.

Grundsätzlich habe ich ein paar Dutzend lmer (.99x-Version von lme4 Paket) Modelle geschätzt und wie die zugehörige Ausgabe, um schließlich in einer Excel-Datei zu In dem Code unten, lmer.stats,lmer.fixef, und lmer.ranef Alle erstellen Datenrahmen basierend auf entsprechenden Ergebnissen. lmer.append werden verwendet, um drei dieser Funktionen und aufzurufen rbind die Ergebnisse.

Da es so viele Modelle gibt, brauchte ich eine zusätzliche ID-Variable Etikette erstellt, um ein Modell von einem anderen zu unterscheidenaggregierte Ausgabe. Die Idee ist, den Argumentnamen zu extrahieren und ihn zu einer Bezeichnervariablen zu machen, mit der ich bis zu den freundlichen Vorschlägen von MrFlick Schwierigkeiten hatte ... fix funktioniert super.

## model summary statistics
lmer.stats<-function(lmer.name) {
A<-AIC(lmer.name)
B<-BIC(lmer.name)
ll<-logLik(lmer.name)
dv<-deviance(lmer.name)
obs.TIME<-length(lmer.name@y)
obs.CHILD<-sapply(ranef(lmer.name),nrow)[1]
names(obs.CHILD)<-NULL
obs.SCHOOL<-sapply(ranef(lmer.name),nrow)[2]
names(obs.SCHOOL)<-NULL
label<-deparse(substitute(lmer.name))
df<-data.frame(label, "AIC"=A, "BIC"=B, "LL"=ll, "DEV"=dv, "N"=obs.TIME, "CHILD"=obs.CHILD, "SCHOOL"=obs.SCHOOL)
}
## random effects
lmer.ranef<-function(lmer.name){
re<-data.frame(summary(lmer.name)@REmat)
re<-subset(re,select=-Name)
label<-deparse(substitute(lmer.name))   # identifier
nr<-nrow(summary(lmer.name)@REmat)
md<-data.frame(rep(label,nr))
colnames(md)<-"Model"

dfr<-data.frame(cbind(md,re))

if (ncol(dfr)==4)   {       # random slope models have additional columns
corr.col<-data.frame(rep(NA,nr))
colnames(corr.col)<-"Corr"
V6.col<-data.frame(rep(NA,nr))
colnames(V6.col)<-"V6"
dfr<-data.frame(cbind(dfr,corr.col,V6.col))
}   else {
dfr<-dfr
}
}
## fixed effects
lmer.fixef<-function(lmer.name){
beta<-data.frame("Beta"=fixef(lmer.name))
se<-data.frame("S.E."=sqrt(diag(vcov(lmer.name))))
vars<-data.frame(row.names(beta))
colnames(vars)<-"Variable"
vars$Variable<-gsub("\)", "", vars$Variable)   # deal with (Intercept)
vars$Variable<-gsub("\(", "", vars$Variable)
label<-deparse(substitute(lmer.name))   # identifier
md<-data.frame(rep(label,length(lmer.name@fixef)))
colnames(md)<-"Model"
row.names(beta)<-NULL
dff<-data.frame(cbind(md,vars,beta,se))
}
## controller
lmer.append<-function(...,append=TRUE)  {
label<<-deparse(substitute(...))
if (!append){
L.stats<<-lmer.stats(...)
L.ranef<<-lmer.ranef(...)
L.fixef<<-lmer.fixef(...)
} else {
L.stats<<-rbind(L.stats, lmer.stats(...))
L.ranef<<-rbind(L.ranef, lmer.ranef(...))
L.fixef<<-rbind(L.fixef, lmer.fixef(...))
}
}

Antworten:

1 für die Antwort № 1

Möglichkeit ist, die Variable "fallen zu lassen" f1 in f2 über das Argument "...".

x=7
f1<-function(a){
label<-deparse(substitute(a))
cat("f1 value:",a,"n")
cat("f1 label:",label,"n")
}

f2<-function(...) {
label<-deparse(substitute(...))
cat("f2 value:",eval(substitute(...)),"n")
cat("f2 label:",label,"n")
f1(...)
}
f2(x)

# f2 value: 7
# f2 label: x
# f1 value: 7
# f1 label: x

Aber es hängt wirklich davon ab, warum Sie diese Anordnung überhaupt haben. Ein natürlicherer Weg könnte dies sein

x=7
f1<-function(a, label=deparse(substitute(a))) {
cat("f1 value:",a,"n")
cat("f1 label:",label,"n")
}

f2<-function(b) {
label<-deparse(substitute(b))
cat("f2 value:",b,"n")
cat("f2 label:",label,"n")
f1(b, label)
}
f2(x)

Was auch zurückkehrt

# f2 value: 7
# f2 label: x
# f1 value: 7
# f1 label: x

und f1(x) kommt immer noch zurück

# f1 value: 7
# f1 label: x