2017-03-21 80 views
0

比方說,我們有一個數據框,其中包含一組3個因變量和6個由分組變量標記的獨立變量。與下面的示例代碼生成此格式的一個例子:如何首先group_by()然後通過列迭代lm()?

library(tidyverse) 
library(broom) 
n <- 15 
df <- data.frame(groupingvar= sample(letters[1:2], size = n, replace = TRUE), 
        y1 = rnorm(n,10,1), y2=rnorm(n,100,10), y3=rnorm(n,1000,100), 
        x1= rnorm(n,10,1), x2=rnorm(n,10,1), x3=rnorm(n,10,1), 
        x4=rnorm(n,10,1), x5=rnorm(n,10,1), x6=rnorm(n,10,1)) 
df <- arrange(df,groupingvar) 

如果我想通過5233退步每個Y1,Y2,Y3對集X1的,我可以沿着線使用的東西:

y <- as.matrix(select(df,y1:y3)) 
x <- as.matrix(select(df,x1:x6)) 
regs <-lm(y~x) 
coeffs <- tidy(regs) 
coeffs <- arrange(coeffs,response, term) 

(通過利用下面的行的從LM()的幫助下:「如果響應是一個矩陣,線性模型分別由最小二乘裝配到矩陣的每一列。」)

但是,如果我需要先由分組變量進行分組,然後應用lm函數,那麼我不太確定如何去做。我嘗試了以下方法,但它爲兩組產生了相同的一組係數。

regs2 <- df %>% group_by(groupingvar) %>% 
    do(fit2 = lm(as.matrix(select(df,y1:y3)) ~ as.matrix(select(df,x1:x6)))) 
coeffs2 <- tidy(regs2,fit2) 
coeffs2 <- arrange(coeffs2,groupingvar, response) 
+0

「然後應用LM功能」' - >'ħ大家試過用lapply()'? – d8aninja

+0

我不確定如何正確使用它。我嘗試創建一個包含元素「y1〜x1 + x2 + ... + x6」,「y2〜x1 + x2 + ... + x6,」y3〜x1 + x2 + ... + x6「的公式列表,以及嘗試將這個列表傳遞給lm(),但我想我正確地使用它的語法。 – user1689945

+0

應用,sapply,lapply等家族對你的理解來說絕對是最重要的。必須學習。有無窮的資源會教你很多在這裏可以看到Hadley的高級R(在線提供)或許多書中的例子 – d8aninja

回答

1

data.table,你可以melt(重塑長 - 疊結果變量在一列中,而不是存儲在三列)雙方groupingvar和結果變量& lm

library(data.table) 
setDT(df) 

#alternatively, set id.vars = c('groupingvar', paste0('x', 1:6)), etc. 
longDT = melt(df, id.vars = grep('y', names(df), invert = TRUE)) 

#this helper function basically splits a named vector into 
# its two components 
coefsplit = function(reg) { 
    beta = coef(reg) 
    list(var = names(beta), coef = beta) 
} 

#I personally wouldn't assign longDT, I'd just chain this onto 
# the output of melt; 
longDT[ , coefsplit(lm(value ~ ., data = .SD)), by = .(groupingvar, variable)] 
#  groupingvar variable   var   coef 
# 1:   a  y1 (Intercept) -3.595564e+03 
# 2:   a  y1   x1 -3.796627e+01 
# 3:   a  y1   x2 -1.557268e+02 
# 4:   a  y1   x3 2.862738e+02 
# 5:   a  y1   x4 1.579548e+02 
# ... 
# 38:   b  y3   x2 2.136253e+01 
# 39:   b  y3   x3 -3.810176e+01 
# 40:   b  y3   x4 4.187719e+01 
# 41:   b  y3   x5 -2.586184e+02 
# 42:   b  y3   x6 1.181879e+02 
#  groupingvar variable   var   coef 
+0

謝謝。我認爲我遵循你的答案。我能夠在R中運行它並且工作。使用linest()函數在Excel中複製結果,並且結果僅匹配第一個分組變量,而它們是signif對於第二個分組變量來說,它們顯然不同。 R和Excel的最小二乘算法是不同的? (2)我同意我不應該分配longDT,因爲行數會顯着增加,但是如何管理熔體的輸出,以便每個係數都可以正確標記攔截,x1等。 – user1689945

+0

結果應該是相同的(推測都使用(X'X)^( - 1)X'Y)。你能具體說明哪個組返回了錯誤的估計,以及R與Excel的輸出是什麼? – MichaelChirico

+0

@ user1689945關於您的第二點,請參閱編輯 – MichaelChirico

0

我還發現一種方法來實現這一點使用cbind()返回如下:

library(tidyverse) 
library(broom) 
n <- 20 
df4 <- data.frame(groupingvar= sample(1:2, size = n, replace = TRUE), 
        y1 = rnorm(n,10,1), y2=rnorm(n,100,10), y3=rnorm(n,1000,100), 
        x1= rnorm(n,10,1), x2=rnorm(n,10,1), x3=rnorm(n,10,1), 
        x4=rnorm(n,10,1), x5=rnorm(n,10,1), x6=rnorm(n,10,1)) 
df4 <- arrange(df4,groupingvar) 

regs <- df4 %>% group_by(groupingvar) %>% 
    do(fit = lm(cbind(y1,y2,y3) ~ . -groupingvar, data = .)) 
coeffs <- tidy(regs, fit)