2016-12-30 15 views
-1

Я только начал изучать R и не могу заставить этот цикл работать. У меня есть кадр данных, содержащий 250 строк и 503 столбца (y) и другой фрейм данных, содержащий 250 строк и 1 столбец (x).Петли в R - линейная регрессия

Я пытаюсь получить цикл для запуска 503 отдельных регрессий без необходимости вводить их отдельно, т.е.

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

через все 250 строк в каждой регрессии.

Я попробовал этот цикл:

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

, но это только дал мне один перехват и один коэффициент, в отличие от 503 перехватов и 503 коэффициентов.

Строки каждого кадра данных имеют метки времени, которые выровнены в формате yyyy-mm-dd, но я не верю, что это влияет на регрессию по мере того, как требуемый выходной сигнал перехвата и коэффициентов не зависит от времени.

Я также попытался использовать основной лм:

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

, и это дает 503 перехватов и 503 коэффициентов, однако выход неправильно, когда я выборочную проверку вывода против некоторых столбцов (работает индивидуальный регресс, как указано выше) ,

Любая помощь в этом цикле очень ценится!

Спасибо

+0

лм (у ~ х), где х больше один столбец представляет собой множественную регрессию, коэффициенты не будут соответствовать коэффициентам из каждой из 503 отдельных регрессий. – Seth

ответ

0

Я не уверен, что вы приближается это лучший способ, но вот то, что я думаю, будет добиться того, что вы описали.

# 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

ваш пример не воспроизводится (попробуйте использовать 'y <- data.frame (replicate (5, runif (250, 0, 1)))' вместо). Но, как комментирует Аарон, вы можете сделать это за один шаг без цикла. 'coef (lm (as.matrix (y) ~ as.matrix (x)))' – user20650

+0

Я понимаю, что цикл не требуется (они когда-либо?), но иногда циклы облегчают понимание происходящего. возможно, не в этом случае. но я не понимаю, почему этот пример не воспроизводится. если я перезапущу R и снова запустил, я получу те же результаты. я что-то упускаю? –

+1

Повторите свой пример, первая строка использует sapply над y, прежде чем y определен (возможно, у вас есть y, загруженный в ваше рабочее пространство при перезагрузке?) – user20650

0

Ваша петля близка вам просто нужно создать место, чтобы поймать результаты.

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

} 

Если вы просто хотите, коэффициенты в виде data.frame затем перестроить вещи, чтобы поймать только двух коэффициентов от каждой модели

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

} 
+0

Это работает! Спасибо. Если я печатаю в "output_loop" в консоли это дает мне все 503 перехватывает и коэффициенты, такие как [[503]] Вызов: лм (формула = у [, я] ~ х) Коэффициенты: (Intercept) x ' Однако я бы потерял заголовок всех 503 столбцов. Есть ли способ сохранить заголовок столбцов и иметь две строки для перехвата и коэффициента? Я пытаюсь изменить варианты: 'output_total <- as.matrix (output_loop)' не повезло. Еще раз спасибо – ejt

+0

Есть пара хороших стратегий. Если все, что вам нужно, это просто перехват и наклон, тогда просто организуйте вывод из списка в фрейм данных. Если вы хотите получить больше материала из регрессионных выходов, то список, который я создал, получает это для вас. Я добавил структурированный результат кадра данных, так что у вас есть оба. – 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