You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于R基础包、weights与survey包的加权列联表P值差异问询

加权列联表P值差异原因及政治调查数据最优方法

咱们先拆解你遇到的核心问题:R基础包、weights包和survey包的结果差异,完全来自它们对「权重」的定义、统计假设以及适用场景的不同,下面详细解释:

一、差异背后的核心逻辑

1. R基础包(含SAS/SPSS基础卡方):频数权重(Frequency Weights)

这里的count变量是频数权重——它代表「这一行的观测重复出现了多少次」,相当于把数据展开成原始的个体级观测后再做卡方检验。比如第一行的count=35,就等于有35条完全一样的「男生、有实习、已注册」的记录。

这种情况下,卡方检验的自由度基于展开后的总样本量计算,统计量反映个体观测之间的关联,所以得到的P值(0.365/0.443)是常规卡方检验的结果,和SAS/SPSS基础包完全一致。

对应的格式化代码:

attach(tt) 
print(tt)
#   sex internship enrollment count
# 1 boys        yes        yes    35
# 2 boys         no        yes    14
# 3 girls        yes        yes    32
# 4 girls         no        yes    53
# 5 boys        yes         no    29
# 6 boys         no         no    27
# 7 girls        yes         no    10
# 8 girls         no         no    23

xx <- xtabs(count ~ internship + enrollment, data = tt)
print(xx)
#           enrollment
# internship no yes
#        no  50  67
#        yes 39  67

chisq.test(xx, correct = F)
# Pearson's Chi-squared test
# data:  xx
# X-squared = 0.81894, df = 1, p-value = 0.3655

chisq.test(xx)
# Pearson's Chi-squared test with Yates' continuity correction
# data:  xx
# X-squared = 0.58989, df = 1, p-value = 0.4425

SAS/SPSS对应代码:

proc freq data=SummerSchool order=data;
    tables Internship*Enrollment / chisq;
    weight Count;
run;
WEIGHT BY COUNT.
CROSSTABS TABLES=INTERNSHIP BY ENROLLMENT /STATISTICS=CHISQ.

2. weights包:分析权重(Analytic Weights)

wtd.chi.sq()默认使用分析权重(也叫抽样权重)——它假设每行是一个独立的「组」,权重代表这个组在总体中的相对重要性,而非重复观测。

计算时,它会调整卡方统计量,把权重作为对总体的加权调整,而非扩大样本量。最终统计量大幅缩小,导致P值(0.864)远大于基础包的结果。

对应的格式化代码:

library(weights)
wtd.chi.sq(internship, enrollment, weight = count)
#      Chisq        df    p.value 
# 0.0293791 1.0000000 0.8639066 

3. survey包:复杂抽样设计权重

survey包是专门为复杂抽样调查(分层抽样、整群抽样,PEW/ANES这类调查的标配)设计的。哪怕你用了ids=~1(简单随机抽样假设),它也会用Rao-Scott调整校正卡方统计量——因为抽样权重会改变方差估计,不能用常规的个体级方差计算。

它的自由度基于设计自由度(这里是原始数据行数-1=7),统计量被进一步校正,所以P值(0.882)和weights包接近,但更严谨,因为它考虑了抽样设计的方差影响。

对应的格式化代码:

library(survey)
tt.d <- svydesign(ids = ~1, data = tt, weights = tt$count)
svychisq(~internship + enrollment, tt.d)
# Pearson's X^2: Rao & Scott adjustment
# data:  svychisq(~internship + enrollment, tt.d)
# F = 0.023599, ndf = 1, ddf = 7, p-value = 0.8822

二、PEW、ANES这类政治调查数据的最优方法

对于PEW、ANES这类全国性复杂抽样调查数据,绝对不能用R基础包的频数权重方法!这类数据的权重是抽样权重(用来校正抽样偏差,比如某些群体抽样比例过高/过低),不是重复观测的频数。如果用基础包的方法,会错误扩大样本量、低估标准误,导致P值偏小,容易得出假阳性结论。

最优选择是使用survey包,步骤如下:

  1. 正确构建抽样设计对象:根据调查文档提供的抽样参数(分层变量strata、整群变量psu、抽样权重weight)定义svydesign,比如ANES的典型代码:
    library(survey)
    anes_design <- svydesign(
        ids = ~psu,          # 初级抽样单元(比如选区)
        strata = ~strata,    # 分层变量(比如地区)
        weights = ~weight,   # 抽样权重变量
        data = anes_data,
        nest = TRUE          # 如果psu在分层内嵌套,需设置为TRUE
    )
    
  2. 计算加权卡方检验:用svychisq()函数,它会自动应用Rao-Scott调整,正确估计抽样设计带来的方差,得到可靠的P值:
    svychisq(~internship + enrollment, design = anes_design)
    

如果你的数据没有复杂抽样设计(仅简单加权),weights包可以用,但对于PEW/ANES这类专业调查,survey包是更严谨、更符合调查设计要求的选择。

内容的提问来源于stack exchange,提问作者Bob

火山引擎 最新活动