survey包分层整群抽样估计:层权重设置与svytotal结果疑问
我来帮你理清这个分层整群抽样的权重设置问题——这确实是survey包使用中容易踩的坑!核心误区在于把层的比例权重当成了抽样膨胀权重,这两个完全不是一回事。下面我会用实际代码示例帮你纠正这个问题,同时解释背后的逻辑。
关键概念先搞懂
在单阶段分层整群抽样里:
- 我们先把总体分成若干层(
strata) - 每层内抽取若干群(
cluster),然后对抽中的群做全面调查 - 这里的抽样权重是每个样本群的膨胀因子:也就是该层内总体群数 ÷ 层内样本群数(等概率抽群的情况)。这个权重的作用是把样本群“放大”到它代表的总体群规模。
你之前用weights=传入未调整的层权重(比如层占总体的比例),这完全不对——层比例是用来加权层估计值的,不是给个体观测的抽样权重!
实际代码示例
1. 模拟数据与总体信息
先构造一个符合场景的数据集:假设我们有2个层,层1有10个群(每个群20个单位),层2有5个群(每个群30个单位);我们在层1抽2个群,层2抽1个群,调查抽中群的所有单位。
set.seed(123) # 保证结果可重复 # 层1的样本数据:2个群,每个群20个单位 stratum1 <- data.frame( stratum = rep("stratum1", 40), cluster = rep(c("clust1", "clust2"), each = 20), x = rnorm(40, mean = 10, sd = 2) # 模拟观测变量x ) # 层2的样本数据:1个群,30个单位 stratum2 <- data.frame( stratum = rep("stratum2", 30), cluster = rep("clust3", 30), x = rnorm(30, mean = 15, sd = 3) ) dat <- rbind(stratum1, stratum2) # 存储每层的总体信息:总群数、样本群数、群规模 pop_info <- data.frame( stratum = c("stratum1", "stratum2"), total_clusters = c(10, 5), sample_clusters = c(2, 1), cluster_size = c(20, 30) )
2. 计算正确的抽样权重
给每个观测值分配抽样权重:每个样本群的膨胀因子是层内总群数 ÷ 层内样本群数,因为每个抽中的群代表这么多的总体群。
# 合并总体信息到样本数据 dat <- merge(dat, pop_info, by = "stratum") # 计算抽样权重:等概率抽群时,每个观测的权重等于群的膨胀因子 dat$sampling_weight <- dat$total_clusters / dat$sample_clusters
3. 创建正确的抽样设计
用svydesign时,必须指定strata(层)、id(群ID),并传入正确的抽样权重;另外加上fpc参数(有限总体校正)能让标准误更准确:
library(survey) # 正确的抽样设计 correct_design <- svydesign( id = ~cluster, # 群标识符 strata = ~stratum, # 层标识符 weights = ~sampling_weight, # 抽样权重 data = dat, fpc = ~total_clusters # 每层的总群数,用于有限总体校正 )
4. 估计总量与均值
现在用svytotal和svymean计算的结果就符合预期了:
# 估计总体总量 svytotal(~x, correct_design) # 估计总体均值 svymean(~x, correct_design)
为什么之前的做法错了?
如果你之前直接把层比例(比如层1占总体的2/3,层2占1/3)作为权重传入,相当于给每个观测值赋予了层的占比,这完全没有体现抽样的膨胀效应——样本群本来就代表了更多的总体群,这个权重根本没把样本放大到总体规模,结果自然不对。
额外注意:不等概率抽群(PPS)
如果你的群是按大小比例抽样(PPS),那抽样权重就不是简单的总群数/样本群数了,而是1/抽样概率——比如某个群的抽样概率是群大小/层内总单位数,那它的权重就是层内总单位数/群大小。这种情况只要把权重换成对应的1/π_j即可,设计的创建方式是一样的。
内容的提问来源于stack exchange,提问作者Jean V. Adams

