我有一个包含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存储在单个数据结构中。必须有一种优雅的方式来做到这一点,但我找不到它。有什么帮助吗?
答案 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)