将lm应用于由帧的第三列定义的数据帧的子集

时间:2011-09-14 10:17:07

标签: r dataframe vectorization

我有一个包含x值向量,y值向量和ID向量的数据框:

x <- rep(0:3, 3)
y <- runif(12)
ID <- c(rep("a", 4), rep("b", 4), rep("c", 4))
df <- data.frame(ID=ID, x=x, y=y)

我想为x的子集创建一个单独的lm,并且y共享相同的ID。以下代码完成了工作:

a.lm <- lm(x~y, data=subset(df, ID=="a"))
b.lm <- lm(x~y, data=subset(df, ID=="b"))
c.lm <- lm(x~y, data=subset(df, ID=="c"))

除了这非常脆弱(未来的数据集可能有不同的ID)和未矢量化。我还想将所有lms存储在单个数据结构中。必须有一种优雅的方式来做到这一点,但我找不到它。有什么帮助吗?

3 个答案:

答案 0 :(得分:10)

使用base函数,您可以split原始数据框并在其上使用lapply

lapply(split(df,df$ID),function(d) lm(x~y,d))
$a

Call:
lm(formula = x ~ y, data = d)

Coefficients:
(Intercept)            y  
    -0.2334       2.8813  


$b

Call:
lm(formula = x ~ y, data = d)

Coefficients:
(Intercept)            y  
     0.7558       1.8279  


$c

Call:
lm(formula = x ~ y, data = d)

Coefficients:
(Intercept)            y  
      3.451       -7.628  

答案 1 :(得分:7)

使用plyr包中的一些魔法。函数dlply采用data.frame,将其拆分,将函数应用于每个元素,并将其合并为list。这非常适合您的应用。

library(plyr)
#fitList <- dlply(df, .(ID), function(dat)lm(x~y, data=dat))
fitList <- dlply(df, .(ID), lm, formula=x~y) # Edit

这将为ID的每个子集创建一个包含模型的列表:

str(fitList, max.level=1)

List of 3
 $ a:List of 12
  ..- attr(*, "class")= chr "lm"
 $ b:List of 12
  ..- attr(*, "class")= chr "lm"
 $ c:List of 12
  ..- attr(*, "class")= chr "lm"
 - attr(*, "split_type")= chr "data.frame"
 - attr(*, "split_labels")='data.frame':    3 obs. of  1 variable:

这意味着您可以对列表进行子集化并使用它。例如,要获取lm模型的系数ID=="a"

> coef(fitList$a)
(Intercept)           y 
   3.071854   -3.440928 

答案 2 :(得分:7)

怎么样

library(nlme) ## OR library(lme4)
lmList(x~y|ID,data=d)