在R中的“加权”回归

14

我创建了一个类似下面这样的脚本来执行我所谓的“加权”回归:

library(plyr)

set.seed(100)

temp.df <- data.frame(uid=1:200,
                      bp=sample(x=c(100:200),size=200,replace=TRUE),
                      age=sample(x=c(30:65),size=200,replace=TRUE),
                      weight=sample(c(1:10),size=200,replace=TRUE),
                      stringsAsFactors=FALSE)

temp.df.expand <- ddply(temp.df,
                        c("uid"),
                        function(df) {
                          data.frame(bp=rep(df[,"bp"],df[,"weight"]),
                                     age=rep(df[,"age"],df[,"weight"]),
                                     stringsAsFactors=FALSE)})

temp.df.lm <- lm(bp~age,data=temp.df,weights=weight)
temp.df.expand.lm <- lm(bp~age,data=temp.df.expand)
你可以看到在temp.df中,每一行都有各自的权重,也就是说总共有1178个样本,但对于那些具有相同bpage的行,它们会被合并为1行,并在weight列中表示。
我使用了lm函数中的weight参数,然后将结果与另一个数据框进行交叉验证,这个数据框是通过"展开" temp.df数据框得到的。但是我发现两个数据框的lm输出不同。
我是否错误地解释了lm函数中的weight参数,并且是否有人能告诉我如何正确地运行回归(即不手动扩展数据框)以适用于像temp.df这样的数据集?谢谢。

这两个回归对我来说产生了相同的结果。 - Vincent Zoonekynd
1
请看“summary”输出,它们是不同的。 - lokheart
5
系数是相同的,但 p 值确实不同。我猜想以下情况。当你扩展数据时,假定观测值是独立的:由于有大量数据,你可以非常自信地估计并且 p 值很低。而使用权重时,观测值数量仍然很少,因此 p 值较高。 - Vincent Zoonekynd
但是两个数据框引用相同的数据集(1178行数据),只是呈现方式不同,temp.df使用200行呈现1178行数据。如果在两个数据框中执行相同的回归分析,则应该呈现相同的p值。我需要解决这个问题,因为在我的情况下,我可能有超过100万行数据,如果我不使用“weight”方法,可能没有足够的内存来存储它们。 - lokheart
@VincentZoonekynd - 确实是这样。摘要直接显示了这一点。summary(temp.df.lm):...残差标准误差:自由度为198的69.89.... summary(temp.df.expand.lm):...残差标准误差:自由度为1176的28.68... - Matthew Lundberg
2
这个问题应该移动到Cross Validated。 - Carlos Cinelli
1个回答

17

这里的问题在于自由度没有被正确地加起来,以便得到正确的自由度和平均平方和统计量。以下方法可以纠正这个问题:

temp.df.lm.aov <- anova(temp.df.lm)
temp.df.lm.aov$Df[length(temp.df.lm.aov$Df)] <- 
        sum(temp.df.lm$weights)-   
        sum(temp.df.lm.aov$Df[-length(temp.df.lm.aov$Df)]  ) -1
temp.df.lm.aov$`Mean Sq` <- temp.df.lm.aov$`Sum Sq`/temp.df.lm.aov$Df
temp.df.lm.aov$`F value`[1] <- temp.df.lm.aov$`Mean Sq`[1]/
                                        temp.df.lm.aov$`Mean Sq`[2]
temp.df.lm.aov$`Pr(>F)`[1] <- pf(temp.df.lm.aov$`F value`[1], 1, 
                                      temp.df.lm.aov$Df, lower.tail=FALSE)[2]
temp.df.lm.aov
Analysis of Variance Table

Response: bp
            Df Sum Sq Mean Sq F value   Pr(>F)   
age          1   8741  8740.5  10.628 0.001146 **
Residuals 1176 967146   822.4        

与之比较:

> anova(temp.df.expand.lm)
Analysis of Variance Table

Response: bp
            Df Sum Sq Mean Sq F value   Pr(>F)   
age          1   8741  8740.5  10.628 0.001146 **
Residuals 1176 967146   822.4                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

我有点惊讶这在R-help上没有更常见。要么我的搜索策略开发能力随着年龄的增长而减弱。


代码的上方块中存在错误(temp.df.lm.aovn Sq' <- temp.df.lm.aov$'Sum Sq'/temp.df.lm.aov$Df)。请注意,该代码未能解决问题(ANOVA表格不同)。 - gung - Reinstate Monica
我尝试进行了更正,请确保您批准。请注意,我使用了子集/索引(即[1]),并且不清楚这是否符合您的风格/普遍性要求。(但是,现在输出与您想要的输出相匹配。) - gung - Reinstate Monica
有语法错误(未匹配的反引号),我没有时间去调查。感谢你尝试修复它。 - IRTFM
1
你好。修正后的代码与正确版本不匹配,例如,p = .18!= p = .001; 我以为您试图表明如果计算 df 正确,则 anova()输出将匹配。这不是您的意思吗? - gung - Reinstate Monica
1
是的。我的意思实际上是你需要将平方和除以正确的自由度,然后重新计算F统计量和Pr(>F) - IRTFM
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接