奇怪现象:在循环内创建的aov()对象中,不同aov对象的数据帧是相同的

时间:2013-03-22 20:49:30

标签: r list dataframe anova

我在循环中运行aov()。每次迭代的输出都保存为列表项。当我使用model.frame()检查每个aov对象的数据帧时,它们都是相同的 - 事实上,它们基本上都是最后一次迭代的数据帧。 更有趣的是,这似乎只适用于包含错误术语的aov模型。为了说明这一点,我使用R中的ChickWeight数据(见下文)

results<-list()
length(results2)<-4
counter<-1
for(i in unique(ChickWeight$Diet)){
results[[counter]] <- aov(weight~factor(Time) + Error(Chick),    
                              ChickWeight[ChickWeight$Diet==i,])
counter<-counter+1
}
head(model.frame(results[[1]]), 2)
#    weight factor(Time) Chick
#461     42            0    41
#462     51            2    41
head(model.frame(results[[2]]), 2)
#    weight factor(Time) Chick
#461     42            0    41
#462     51            2    41
head(model.frame(results[[3]]), 2)
#    weight factor(Time) Chick
#461     42            0    41
#462     51            2    41
head(model.frame(results[[4]]), 2)
#    weight factor(Time) Chick
#461     42            0    41
#462     51            2    41

相反,当没有错误术语时,这不会发生:

results2<-list()
length(results2)<-4
counter<-1
for(i in unique(ChickWeight$Diet)){
results2[[counter]] <- aov(weight~factor(Time),    
                               ChickWeight[ChickWeight$Diet==i,])
counter<-counter+1
}
head(model.frame(results2[[1]]), 2)
#  weight factor(Time)
#1     42            0
#2     51            2
head(model.frame(results2[[2]]), 2)
#    weight factor(Time)
#221     40            0
#222     50            2
head(model.frame(results2[[3]]), 2)
#    weight factor(Time)
#341     42            0
#342     53            2
head(model.frame(results2[[4]]), 2)
#    weight factor(Time)
#461     42            0
#462     51            2

我想知道是否有人知道发生了什么。

1 个答案:

答案 0 :(得分:2)

据我了解,如果错误术语是模型的一部分model.frame.aovlist通过评估拟合的调用属性来获取数据,即- attr(*, "call")= language aov(formula = weight ~ factor(Time) + Error(Chick), data = ChickWeight[ChickWeight$Diet == i, ])。如您所见,调用取决于i的值。此外,aovlist对象保存环境名称以查找数据。在这种情况下,它是R_GlobalEnv

看看这个:

results<-list()
counter<-1
for(i in unique(ChickWeight$Diet)){
  results[[counter]] <- aov(weight~factor(Time) + Error(Chick),    
                            data=ChickWeight[ChickWeight$Diet==i,])
  counter<-counter+1
}

head(model.frame(results[[1]]), 2)
#     weight factor(Time) Chick
# 461     42            0    41
# 462     51            2    41

i <- 1
head(model.frame(results[[1]]), 2)
#   weight factor(Time) Chick
# 1     42            0     1
# 2     51            2     1

如果使用split-apply-combine方法,则可以避免此问题。以下是使用by

的示例
res <- by(ChickWeight,ChickWeight$Diet,FUN=function(DF) {
  aov(weight~factor(Time)+ Error(Chick) ,    
      data=DF)
})

head(model.frame(res[[1]]),2)
#  weight factor(Time) Chick
#1     42            0     1
#2     51            2     1

使用这种方法,可以保存查找数据的正确环境,即传递给by的匿名函数调用环境。