按群体概率抽取数据框唯一ID的R代码报错及解决方案咨询
解决R语言分层抽样的概率分配问题
首先还原你的场景,你构建的数据框是这样的:
ID <- c(1,2,3,4,5,6) pop <- c(10,10,10,10,1000,1000) df <- data.frame(pop,ID)
你的需求很明确:抽取3个唯一ID,其中pop≥1000的ID组总抽取概率为0.1,pop<1000的ID组总概率为0.9。但你写的代码运行报错了:
你写的代码:
sample(c(df$ID[df$pop>=1000],df$ID[df$pop<1000]),3, prob=c(0.1,0.9))
错误信息:
Error in sample.int(length(x), size, replace, prob) : incorrect number of probabilities
为啥会报错?
其实这个错误原因很直白:sample函数的prob参数长度必须和你要抽样的向量长度完全一致。你要抽样的是6个ID的向量,但只给了2个概率值,R自然不知道怎么对应,所以就报错了。
不用逐个分配概率的解决方法
咱们不用手动给每个ID写概率,只需要基于组的大小把总概率均分在组内每个ID上就行,这样既能满足组总概率的要求,又不用重复写代码。
方法一:自动生成组内权重(基础R实现)
我们可以给每个ID计算一个组内权重:高pop组(≥1000)的总概率是0.1,组内有2个ID,所以每个ID的概率是0.1/2;低pop组(<1000)总概率0.9,组内有4个ID,每个ID的概率是0.9/4。用代码实现就是:
# 给每个ID添加组内权重列 df$group_prob <- ifelse( df$pop >= 1000, 0.1 / sum(df$pop >= 1000), # 高pop组每个ID的概率 0.9 / sum(df$pop < 1000) # 低pop组每个ID的概率 ) # 基于权重抽取3个唯一ID selected_ids <- sample(df$ID, size = 3, prob = df$group_prob, replace = FALSE) selected_ids
这样运行后,高pop组的两个ID总概率加起来是0.1,低pop组四个ID总概率加起来是0.9,完全符合你的需求,而且不管组内ID数量怎么变,代码都能自动适配,不用手动调整概率值。
方法二:分层抽样(用sampling包简化操作)
如果你习惯用专门的抽样包,可以试试sampling包的strata函数,它专门处理分层抽样的场景,你只需要指定分层变量、每层的抽样概率或者数量:
# 先安装并加载包(第一次用需要安装) # install.packages("sampling") library(sampling) # 分层抽样:指定分层变量是pop的分组,总样本量3,每层的抽样数量基于总概率计算 strata_sample <- strata( data = df, stratanames = "pop", # 按pop分层 size = c(round(3*0.9), round(3*0.1)), # 低pop组抽2个,高pop组抽1个 method = "srswor" # 无放回抽样 ) # 提取选中的ID selected_ids <- df$ID[strata_sample$ID_unit] selected_ids
这个方法更直观,直接按组分配抽样数量,也不用手动给每个ID写概率。
内容的提问来源于stack exchange,提问作者Mucteam
相关产品推荐
相关产品推荐

