2016-12-30 19 views
-1

Ich habe gerade angefangen, R zu lernen und kann nicht scheinen, dass diese Schleife funktioniert. Ich habe einen Datenrahmen mit 250 Zeilen und 503 Spalten (y) und einen weiteren Datenrahmen mit 250 Zeilen und 1 Spalte (x).Loops in R - lineare Regression

Ich versuche eine Schleife zu bekommen, um 503 separate Regressionen auszuführen, ohne sie einzeln eingeben zu müssen, dh.

(output_1 <- lm(y$1st column ~ x)) 
(output_2 <- lm(y$2nd column ~ x)) 

über alle 250 Zeilen in jeder Regression.

Ich habe versucht, diese Schleife:

for (i in 1:503) { 
output_loop <- lm(y[,i]~x) 
} 
output_total <- cbind(output$coefficients) 

aber das gab mir nur einen Schnittpunkt und einen Koeffizienten, wie bis 503 abfängt und 503 Koeffizienten gegenüber.

Die Zeilen jedes Datenrahmens haben Zeitmarken, die im Format JJJJ-MM-TT ausgerichtet sind, aber ich glaube nicht, dass dies die Regression beeinflusst, da der gesuchte Abschnitt und die ausgegebenen Koeffizienten unabhängig von der Zeit sind.

ich auch eine grundlegende lm versucht habe, mit:

(output <- lm(y~x)) 
output_total <- cbind(output$coefficients) 

und das gibt 503 abfängt und 503 Koeffizienten, aber der Ausgang ist falsch, wenn ich vor Ort die Ausgabe gegen einige Spalten geprüft (wie oben einzelne Regression ausgeführt wird) .

Jede Hilfe auf dieser Schleife wird sehr geschätzt!

Danke

+0

lm (y ~ x), wobei x mehr als Eine Spalte ist eine multiple Regression, die Koeffizienten stimmen nicht mit den Koeffizienten von jeder der 503 separaten Regressionen überein. – Seth

Antwort

0

Ich bin nicht sicher, Sie dies der beste Weg sind nähern, aber hier ist etwas, das ich erreichen denken, was Sie beschrieben.

# create some toy data to match your description 

set.seed(340) 
y <- data.frame(replicate(503, runif(250, 0, 1))) 
x <- data.frame(v1=runif(250, 0, 1)) 


out <- data.frame(NULL)    # create object to keep results 
for (i in 1:length(y)) { 
    m <- summary(lm(y[,i] ~ x[,1])) # run model 
    out[i, 1] <- names(y)[i]   # print variable name 
    out[i, 2] <- m$coefficients[1,1] # intercept 
    out[i, 3] <- m$coefficients[2,1] # coefficient 
} 
names(out) <- c("y.variable", "intercept", "coef.x") 
head(out) 

# y.variable intercept  coef.x 
# 1   X1 0.4841710 -0.015186852 
# 2   X2 0.4972775 -0.002306964 
# 3   X3 0.4410326 0.096450185 
# 4   X4 0.4547249 0.041582039 
# 5   X5 0.5039661 0.062429142 
# 6   X6 0.5331573 -0.092806309 
+0

Ihr Beispiel ist nicht reproduzierbar (versuchen Sie stattdessen mit 'y <- data.frame (replicate (5, runif (250, 0, 1)))'). Aber wie Aaron bemerkt, können Sie dies ohne Schleife in einem Schritt tun. 'coef (lm (as.matrix (y) ~ as.matrix (x))) ' – user20650

+0

ich bekomme, dass eine Schleife nicht erforderlich ist (sind sie überhaupt?), aber manchmal Schleifen machen es leichter zu verstehen, was passiert. vielleicht nicht in diesem Fall. aber ich folge nicht, warum das Beispiel nicht reproduzierbar ist. Wenn ich R neu starte und wieder laufe, bekomme ich die gleichen Ergebnisse. vermisse ich etwas? –

+1

Für Ihr Beispiel, die erste Zeile verwendet Sapply über y, bevor y definiert ist (vielleicht haben Sie eine y geladen in Ihrem Arbeitsbereich, wenn Sie neu starten ??) – user20650

0

Ihre Schleife ist in der Nähe Sie müssen nur einen Ort erstellen, um die Ergebnisse zu erfassen.

output_loop=list(NA) 
for (i in 1:503) { 
output_loop[[i]] <- lm(y[,i]~x) 

} 

Wenn Sie nur die Koeffizienten in einem data.frame dann Dinge wollen restrukturieren nur die beiden Koeffizienten von jedem Modell zu fangen

output_loop=data.frame(int=NA,slope=NA) 
for (i in 1:503) { 
    output_loop[i,] <- coefficients(lm(y[,i]~x)) 

} 
+0

Das funktioniert! Vielen Dank. Wenn ich "output_loop" in der Konsole eingeben es gibt mir alle 503 abfängt und Koeffizienten wie '[[503]] Call: lm (Formel = y [i] ~ x) Koeffizienten: (Abschnitt) x ' Allerdings würde ich den Header aller 503 Spalten verlieren. Gibt es eine Möglichkeit, den Header der Spalten beizubehalten und zwei Zeilen für den Achsenabschnitt und den Koeffizienten zu haben? Ich versuche Variationen von: 'output_total <- as.matrix (output_loop)' ohne Glück. Danke nochmal – ejt

+0

Es gibt ein paar gute Strategien. Wenn alles, was Sie wollen, nur der Schnittpunkt und die Steigung ist, organisieren Sie einfach die Ausgabe von einer Liste zu einem Datenrahmen. Wenn Sie mehr Zeug aus den Regressionsausgaben möchten, dann bekommt die Liste, die ich eingerichtet habe, das für Sie. Ich fügte das strukturierte Ergebnis des Datenrahmens hinzu, also haben Sie beide. – Seth

0
# libraries 
library('purrr') 
library('data.table') 

# data 
set.seed(340) 
df1 <- data.frame(x=runif(250, 0, 1), 
        replicate(503, runif(250, 0, 1))) 
setDT(df1) 
df1 <- melt.data.table(df1, id = 'x', variable.factor = FALSE, value.name = 'y') 

# apply lm() on data df1 
model_lm_rsqr <- df1 %>% 
    split(.$variable) %>% 
    map(~ lm(y ~ x, data = .)) %>% 
    map(summary) %>% 
    map_dbl("r.squared") 

model_lm_coeff <- df1 %>% 
    split(.$variable) %>% 
    map(~ lm(y ~ x, data = .)) %>% 
    map(summary) %>% 
    map("coefficients") 

# outputs 
model_lm_rsqr['X1'] 
# X1 
# 7.381324e-05 

model_lm_coeff[['X1']] 
# Estimate Std. Error t value  Pr(>|t|) 
# (Intercept) 0.500224626 0.03534444 14.1528503 9.867274e-34 
# x   -0.008564851 0.06330103 -0.1353035 8.924817e-01 


rbindlist(l = lapply(map(.x = model_lm_coeff, .f = ~ {t(.x[,1])}), as.data.frame), idcol = TRUE) 

# .id (Intercept)   x 
# 1: X1 0.5002246 -0.008564851 
# 2: X10 0.4759053 0.035537332 
# 3: X100 0.5200009 -0.078890569 
# 4: X101 0.4804617 0.096970266 
# 5: X102 0.5593092 -0.077299502 
# ---        
# 499: X95 0.5413627 -0.017625063 
# 500: X96 0.5016745 -0.093123400 
# 501: X97 0.5449859 -0.060117246 
# 502: X98 0.4670116 0.110287578 
# 503: X99 0.5121481 -0.042537902