按组加权随机抽取data.table样本的实现方法求助
按指定频率分组抽样的解决方案
我来帮你搞定这个按组指定频率抽样的需求!你的核心诉求是根据给定的频率分布,计算每个Country组需要抽取的样本量(频率×总样本量),然后在每组内随机抽取对应数量的行对吧?下面是具体的实现步骤和代码:
步骤1:准备数据
先把你的测试数据加载好(确保已经安装并加载data.table包):
library(data.table) # 输入数据 InputDT <- data.table( Country = c(rep("A",20), rep("B",10), rep("C",5), rep("D",2)), ID = c(1:20, 101:110, 201:205, 301:302) ) # 指定的频率分布 CountryFreq <- data.table( Country = unique(InputDT$Country), Freq = c(4/10, 2/10, 2/10, 2/10) ) # 总样本量 Sample_Size <- 10
步骤2:计算每组抽样数量并执行抽样
接下来我们合并数据、计算每组需要抽取的行数,然后完成分组抽样:
# 合并输入数据和频率表,为每行添加对应Country的频率 InputDT_with_freq <- InputDT[CountryFreq, on = "Country"] # 计算每组需要抽取的样本量:频率×总样本量 InputDT_with_freq[, n_to_sample := Freq * Sample_Size] # 关键:确保抽样数量不超过每组的实际行数(避免因频率计算值大于组内行数报错) InputDT_with_freq[, n_to_sample := pmin(n_to_sample, .N), by = Country] # 按Country分组,随机抽取对应数量的行 OutputDT <- InputDT_with_freq[, .SD[sample(.N, n_to_sample[1])], by = Country] # 清理不需要的列,得到最终结果 OutputDT[, c("Freq", "n_to_sample") := NULL]
步骤3:验证结果
执行完抽样后,你可以用以下代码验证频率是否符合预期:
# 查看分组频率分布 table(OutputDT$Country) / nrow(OutputDT) # 或者用Hmisc包的describe函数 library(Hmisc) describe(OutputDT$Country)
运行后你会看到和你手动示例一致的频率分布:A占40%,B、C、D各占20%。
注意事项
- 如果
Freq * Sample_Size得到的是小数,你可以根据需求用round()、ceiling()或floor()调整抽样数量,比如n_to_sample := round(Freq * Sample_Size); - 确保
CountryFreq中的Country值和InputDT完全匹配,避免合并后出现NA行; - 代码中用
pmin(n_to_sample, .N)是为了防止某组的计算抽样量超过该组实际存在的行数,比如如果某Country只有1行,但频率计算需要抽2行,这时候会自动抽取全部1行。
内容的提问来源于stack exchange,提问作者watchtower
相关产品推荐
相关产品推荐

