按函数应用于lm()

时间:2012-07-01 18:21:16

标签: r

我是R的新手,我刚学习apply函数及其工作原理。我只想在几年内通过产品颜色和品牌从变量x的lm拟合中提取系数。

我知道我可以创建一个for循环并按模型年份对数据进行子集化并适合它,但我认为我开始使用更多内置函数的时间,所以我希望能够使用by函数或者应用功能。这就是我的想法。

#some made up data

x<-rnorm(50,13400,1200)
color<-sample(factor(c("Red","Black","Blue","Green","White")),50,replace=T)
year<-sample(factor(2006:2012),50,replace=T)
brand<-sample(factor(c("A","B","C","D")),50,replace=T)

d<-data.frame(x,color,year,brand)

#now I want to fit the model lm(x~color+brand) for each year level
#this is what I was thinking...

tmp<-with(d,by(x,year,function(y) lm(x~color,data=y)))
sapply(tmp,coef)
  

eval中的错误(predvars,data,env):数字'envir'arg不是长度为1

当我输入help(by)

时,我基于R给出的exapmle

3 个答案:

答案 0 :(得分:5)

请改为尝试:

tmp <- by(d, year, function(d.subset) lm(x~color, data=d.subset))

答案 1 :(得分:5)

除了使用基本R功能(这是一个了解它们如何工作的好主意)之外,还值得研究之前可能已经开展过工作的人。将线性模型拟合到数据集的每个子集是一堆事情,结果发现人们已经专门为此构建了一些方便的工具。

尝试查看 lme4 包和函数lmList。来自?lmList中的示例,

(fm1 <- lmList(Reaction ~ Days | Subject, sleepstudy))

分别适合每个Reaction ~ Days的线性模型Subject。这很方便,因为提取器方法直接在fm1

上工作
> coef(fm1)
    (Intercept)      Days
308    244.1927 21.764702
309    205.0549  2.261785
310    203.4842  6.114899
330    289.6851  3.008073
331    285.7390  5.266019
332    264.2516  9.566768
333    275.0191  9.142045
334    240.1629 12.253141
335    263.0347 -2.881034
337    290.1041 19.025974
349    215.1118 13.493933
350    225.8346 19.504017
351    261.1470  6.433498
352    276.3721 13.566549
369    254.9681 11.348109
370    210.4491 18.056151
371    253.6360  9.188445
372    267.0448 11.298073

(行号是Subjects的id值)请参阅?lmList处的帮助文件,了解其他方法可用于置信区间,绘图等等。

答案 2 :(得分:1)

这在更现代的包装中更容易,例如data.table

library(data.table)
setDT(d)
d[ , .(reg = list(lm(x ~ color))), by = year]
#    year  reg
# 1: 2012 <lm>
# 2: 2006 <lm>
# 3: 2011 <lm>
# 4: 2008 <lm>
# 5: 2007 <lm>
# 6: 2010 <lm>
# 7: 2009 <lm>

reg列包含lm个对象;请注意,我们需要在lm中包含list(.),以便data.table不会混淆普通列表(请注意is.list(lm(x ~ color, data = d))TRUE