2015-11-02 6 views
8
nennt

Hier ist mein Problem (fiktive Daten, um reproduzierbar zu sein):ein Gewicht Argument in einer Liste von lm Verwenden lapply

set.seed(42) 
df<-data.frame("x"=rnorm(1000),"y"=rnorm(1000),"z"=rnorm(1000)) 
df2<-data.frame("x"=rnorm(100),"y"=rnorm(100),"z"=rnorm(100)) 
breaks<-c(-1000,-0.68,-0.01315,0.664,1000) 
divider<-cut(df$x,breaks) 
divider2<-cut(df2$x,breaks) 
subDF<-by(df,INDICES=divider,data.frame) 
subDF2<-by(df2,INDICES=divider2,data.frame) 
reg<-lapply(subDF,lm,formula=x~.) 
pre<-lapply(1:4,function(x){predict(reg[[x]],subDF2[[x]])}) 
lapply(1:4,function(x){summary(reg[[x]])$r.squared}) 

Der obige Code funktioniert gut. Was ich mache, ist folgendes: Nach den Werten von x spalte ich df in 4 Datenrahmen und führe eine Regression für jeden dieser Datenrahmen durch, um Werte für einen anderen Datensatz vorhersagen zu können. Die Aufteilung des Datenrahmens soll eine bessere Vorhersage ermöglichen, da der Bereich von x einen großen Einfluss auf die tatsächlichen Daten hat.

Was ich versuche, ist, ein Gewichtungsargument für die Regression hinzuzufügen, um den neuesten Daten größere Bedeutung zu geben. Mein Gewichtungsargument lautet: weights<-0.999^seq(250,1,by=-1), wenn 250 Daten vorhanden sind. Mit einem Samen von 42 und den vorherigen Pausen, alle 4 Dimensionen sind 250

Wenn ich versuche, reg<-lapply(subDF,lm,formula=x~.,weights=0.999^seq(250,1,by=-1)) zu tun, ich habe diesen Fehler:

Error in eval(expr, envir, enclos) : 
    ..2 used in an incorrect context, no ... to look in 

die ziemlich merkwürdig ist als lapply ein ... hat Argument, hier für die formula verwendet, aber es akzeptiert nicht die weights.

Also ich weiß wirklich nicht, was ich tun soll, um diese Gewichte hinzuzufügen. Was muss ich in meinem Code korrigieren oder sollte ich (fast) vollständig ändern, um die Gewichte zu verwenden? Für das Beispiel und um es (vielleicht) einfacher zu machen, schneide ich die Pausen so, dass die 4 Teilmengen die gleiche Dimension haben, aber im Idealfall würde die Antwort auch dann funktionieren, wenn die 4 Teilmengen nicht die gleiche Dimension haben mit Brüchen

This Post auf CrossValidated hat ziemlich das gleiche Problem, aber ohne eine funktionierende Lösung, so dass mir nicht geholfen hat.

Antwort

3

Ich weiß nicht, warum Sie den Fehler bekommen haben (ich dachte, das ....-Argument wurde dafür gemacht. Allerdings habe ich eine kleine Problemumgehung gefunden, ist dies in der Richtung was Sie brauchen? Was ich getan habe ist eine ‚anonyme‘ -Funktion innerhalb lapply erstellt, die die Gewichte (abhängig von der Dimension der Daten) und gibt ein Modell

reg2 <- lapply(subDF, function(chunk){ 
    #calculate weights (!dependent on data ordering) 
    weights <- 0.999^seq(nrow(chunk),1,by=-1) 

    #fit model 
    fit <- lm(x~., data=chunk, weights=weights) 
    return(fit) 
}) 
+0

das ist wirklich toll! Vielleicht wird jemand wissen, was das Problem war, aber Ihre Antwort ist, was ich gesucht habe – etienne

+1

Gern geschehen! Beachten Sie, dass Ihre aktuellen Gewichtungen auf der Reihenfolge Ihres Datenrahmens basieren. Das macht mich immer irgendwie nervös, es wäre sicherer, etwas wie 'Gewichte <- Gewichte [Reihenfolge (Datum $ Zeit, Abnehmen = T)] oder ähnliches zu machen. – Heroka

6

haben wohl die, aus erster Hand, Sie Leider erfahren übelsten Fehler in R. die berechnet., sogenannter Nicht-Standard-Auswertungsfehler (NSE)

Nach ein wenig Ausgrabung im Code denke ich, dass ich den Schuldigen gefunden habe es. Lassen Sie uns einen nehmen die Dinge nach dem anderen:

Zunächst einmal wollen wir uns die traceback() einen Blick:

weights <- 0.999^seq(250,1,by=-1) 

lapply(subDF, lm, formula=x~., weights=weights) 
Error in eval(expr, envir, enclos) : 
    ..2 used in an incorrect context, no ... to look in 
> traceback() 
8: eval(expr, envir, enclos) 
7: eval(extras, data, env) 
6: model.frame.default(formula = ..1, data = X[[1L]], weights = ..2, 
     drop.unused.levels = TRUE) 
5: stats::model.frame(formula = ..1, data = X[[1L]], weights = ..2, 
     drop.unused.levels = TRUE) 
4: eval(expr, envir, enclos) 
3: eval(mf, parent.frame()) 
2: FUN(X[[1L]], ...) 
1: lapply(subDF, lm, formula = x ~ ., weights = weights) 

Es sieht aus wie das Problem in der model.frame.default auftritt. Schauen wir uns also den Quellcode an. Ich werde nicht den gesamten Quellcode schreiben, aber wenn Sie model.frame.default in der Konsole eingeben, werden Sie irgendwo in der Mitte sehen:

extras <- substitute(list(...)) 
extranames <- names(extras[-1L]) 
extras <- eval(extras, data, env) 

Die letzte Zeile ist, wo es fehlschlägt. Die erste Zeile heißt NSE und wird von substitute erstellt. substitute wird erstellt, was ein expression genannt wird, also sagen wir mal so etwas wie ein zu bewertendes Objekt (d. H.erstellt) später innerhalb von eval. Wie Sie in eval sehen können, wird extras in data ausgewertet und dann, wenn nicht in env gefunden. Für die Formel ist es in Ordnung, weil es in den Daten ausgewertet wird und x~. wird eval mitteilen, alle Spalten in data zu verwenden. weights ist aber nicht in der data. Daher wird eval in env suchen. Aber was ist env?

Offenbar env ist eine Umgebung, und ist innerhalb model.frame.default in der Zeile erstellt:

env <- environment(formula$terms) 

Also, was bedeutet das? Nehmen wir ein anderes Beispiel sehen:

xtest <- function(x) { 
    new_func <- function(x) { 
    env <- environment(x) 
    print(env) 
    } 
    new_func(x) 
} 

> xtest(x~z) 
<environment: R_GlobalEnv> 

In der obigen Funktion ich versuche, weniger Zeilen zu replizieren in welchem ​​env in model.frame.default sein wird. Wie Sie sehen können, zeigt environment(formula) auf die globale Umgebung.

So ist es dort, wo env versucht ..2 das heißt das zweite Argument in ... (das heißt weights) weitergegeben zu finden, aber da es keine ... in der globalen Umwelt ist, erhalten Sie einen Fehler. Hoffe es ist jetzt klar!

Beste Lösung und was ich tun würde ist @Heroka Antwort verwenden, um es zu lösen (oder Sie könnten die ganze model.frame.default und lm von Grund auf ohne NSE neu schreiben, aber ich denke, das erste ist vernünftiger :)).

+0

das ist super danke! Ich habe auch versucht, 'w <-0.99^seq (1000,1, by = -1) df <-cbind (df, w)' zu machen, um die Gewichte in den Daten zu haben, aber es immernoch fehlschlägt. Angesichts der Tatsache, dass die Gewichte nun in den Daten enthalten sind, wissen Sie warum? – etienne

+0

Wie ist dann dein 'lapply' Anruf? – LyzandeR

+0

'lapply (subDF, lm, formel = x ~ y + z, gewichte = w)' – etienne

Verwandte Themen