2016-09-01 8 views
2

Ich bin neu in R und ich möchte das folgende Skript mit einer *apply Funktion verbessern (ich habe über apply gelesen, aber ich konnte es nicht verwenden). Ich möchte lm Funktion auf mehrere unabhängige Variablen verwenden (die Spalten in einem Datenrahmen sind). Ich benutzteAnpassen eines linearen Modells mit mehreren LHS

for (i in (1:3) { 
    assign(paste0('lm.',names(data[i])), lm(formula=formula(i),data=data)) 
    } 

Formula(i) definiert als

formula=function(x) 
{ 
    as.formula (paste(names(data[x]),'~', paste0(names(data[-1:-3]), collapse = '+')), env=parent.frame()) 
} 

Danke.

Antwort

5

Wenn ich Sie falsch nicht bekommen, arbeiten Sie mit einem Datensatz wie folgt aus:

set.seed(0) 
dat <- data.frame(y1 = rnorm(30), y2 = rnorm(30), y3 = rnorm(30), 
        x1 = rnorm(30), x2 = rnorm(30), x3 = rnorm(30)) 

x1, x2 und sind Kovariaten, während y1, y2 und y3 drei unabhängige Antwort sind. Sie versuchen, drei lineare Modelle zu passen:

y1 ~ x1 + x2 + x3 
y2 ~ x1 + x2 + x3 
y3 ~ x1 + x2 + x3 

Derzeit verwenden Sie eine Schleife durch y1, y2, y3, passend ein Modell pro Zeit. Und Sie hoffen, den Prozess zu beschleunigen, indem Sie die for Schleife mit sagen wir lapply ersetzen.

Ich möchte darauf hinweisen, dass Sie auf der falschen Spur sind.lm() ist eine teure Operation. Solange Ihr Datensatz nicht klein ist, sind die Kosten der for Schleife vernachlässigbar. Ersetzen for Schleife mit lapply gibt keine Leistungssteigerungen.

Da Sie für alle drei Modelle die gleiche RHS haben, ist die Modellmatrix für drei Modelle gleich. Daher muss die QR-Faktorisierung für alle Modelle nur einmal durchgeführt werden. lm ermöglicht dies, und Sie können verwenden:

fit <- lm(cbind(y1, y2, y3) ~ x1 + x2 + x3, data = dat) 
#Coefficients: 
#    y1   y2   y3  
#(Intercept) -0.081155 0.042049 0.007261 
#x1   -0.037556 0.181407 -0.070109 
#x2   -0.334067 0.223742 0.015100 
#x3   0.057861 -0.075975 -0.099762 

Wenn Sie str(fit) überprüfen, werden Sie sehen, dass dies nicht eine Liste von drei linearen Modellen ist; stattdessen ist es ein einzelnes lineares Modell mit einem einzelnen Objekt $qr, aber mit mehreren LHS. So sind $coefficients, $residuals und $fitted.values Matrizen.

Wenn Sie viel mehr Kovariaten haben, können Sie mit der Eingabe oder Einfügen Formel vermeiden, indem . mit:

fit <- lm(cbind(y1, y2, y3) ~ ., data = dat) 
#Coefficients: 
#    y1   y2   y3  
#(Intercept) -0.081155 0.042049 0.007261 
#x1   -0.037556 0.181407 -0.070109 
#x2   -0.334067 0.223742 0.015100 
#x3   0.057861 -0.075975 -0.099762 

Vorsicht: Schreiben Sie nicht:

y1 + y2 + y3 ~ x1 + x2 + x3 

Dieser Wille Behandle y = y1 + y2 + y3 als eine einzelne Antwort. Verwenden Sie cbind().


Follow-up:

Vielen Dank für Ihre Antwort. Ich bin an einer Verallgemeinerung interessiert.Lass mich genauer sein. Ich habe einen Datenrahmen df, wobei erste n Spalten unabhängige Variablen sind (y1,y2,y3,....) und nächste m Spalten sind die abhängigen Variablen (x1+x2+x3+....). Für n=3 und m=3 ist es der Fall mit fit <- lm(cbind(y1, y2, y3) ~ ., data = dat)). Aber wie kann das automatisch gemacht werden, indem man die Struktur des df verwendet. Ich meine etwas wie (for i in (1:n)) fit <- lm(cbind(df[something] ~ df[something], data = dat)). Das "Etwas" habe ich mit paste und paste0 erstellt. Vielen Dank.

Sie noch die Modellformel durch paste und paste0 erstellen:

paste0("cbind(", paste(names(df)[1:n], collapse = ", "), ")", " ~ .") 

Zum Beispiel mit iris-Datensatz:

paste0("cbind(", paste(names(iris)[1:2], collapse = ", "), ")", " ~ .") 
# "cbind(Sepal.Length, Sepal.Width) ~ ." 

Sie können diese Zeichenfolge Formel passieren zu lm, wie lm wird es automatisch in die Formelklasse zwingen.

+0

Hallo, und danke für Ihre Antwort. Ich bin an einer Verallgemeinerung interessiert. Lass mich genauer sein. Ich habe einen Datenrahmen (df), wobei die ersten n Spalten unabhängige Variablen (y1, y2, y3, ....) sind und die nächsten m Spalten die abhängigen Variablen (x1 + x2 + x3 + ....) sind. Für n = 3 und m = 3 ist dies der Fall mit fit <- lm (cbind (y1, y2, y3) ~., Daten = dat)). Aber wie kann das automatisch gemacht werden, indem man die Struktur des df benutzt? Ich meine etwas wie (für i in (1: n)) passen <- lm (cbind (df [etwas] ~., Daten = dat)). Sollte ich die df - für (für i in (1: n)) teilen? Y (i) <- df [i]? Oder eine Alternative bei. Vielen Dank. –

+0

Ja, das hat es perfekt gemacht. Vielen Dank! –

+0

Natürlich, aber wie wählt man? –

Verwandte Themen