You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言dplyr包实现大数据框按组比例分配抽样及约束设置

R实现精确按组比例分配抽样

你之前的代码用全局slice_sample加权抽样属于概率抽样,无法保证每个组恰好抽到预设的Ni数量,也容易遗漏样本量极小的分组。要实现精确匹配分组抽样量、覆盖全部分组,直接按组嵌套抽样即可,具体实现如下:


1. 数据准备与样本量计算

首先加载依赖、构造示例数据,同时实现Ni=0时强制抽1个的规则:

library(tidyverse)
# 构造示例数据集
var   = c(rep("a",440), rep("b",255) ,rep("c",333),rep("d",47) ,rep("e",159),rep("f",67) ,rep("g",133),
          rep("h",342), rep("i",131) ,rep("j",606),rep("k",129),rep("l",126),rep("m",155),rep("n",62),
          rep("o",616), rep("p", 173),rep("q",430),rep("r",2)  ,rep("s",453),
          rep("t",154), rep("v",145),rep("u", 307),rep("w",233),rep("x",315),rep("y",65),rep("z",159),
          rep("aa",758),rep("ab",307),rep("ac", 413),rep("ad",184),rep("ae",334),rep("af",111),rep("ag",175),
          rep("ah", 262),rep("ai",309),rep("aj",71),rep("ak",35),rep("al",302),
          rep("am",266), rep("an",36),rep("ao",47),rep("ap",415),rep("aq",204),rep("ar",259))
value = rnorm(10525)
dat = tibble(var,value)

# 计算各组目标抽样量
sample_plan <- dat %>%
  group_by(var) %>%
  summarise(
    group_total = n(),        # 组内总观测数
    group_weight = group_total/nrow(.), # 组占总样本权重
    target_n = round(group_total * group_weight) # 比例分配初始抽样量
  ) %>%
  # 约束规则:计算得到的抽样量为0时,强制抽1个
  mutate(target_n = ifelse(target_n == 0, 1, target_n))

补充:如果存在极小样本组出现「目标抽样量大于组内总观测数」的情况,可以把规则改为target_n = pmin(group_total, ifelse(target_n == 0, 1, target_n)),避免抽样时报错。


2. 按组精确抽样

核心逻辑是分组后在组内独立抽样,从根源上保证每个组都被抽到、且抽样量完全匹配预设值:

set.seed(1234) # 设置随机种子,保证结果可复现
result_sample <- dat %>%
  left_join(sample_plan, by = "var") %>%
  group_by(var) %>%
  # 组内无放回抽取对应数量样本,first()取组内统一的target_n值
  slice_sample(n = first(target_n), replace = FALSE) %>%
  ungroup()

3. 结果校验

抽样完成后可以做三层校验,确保结果符合要求:

# 统计实际抽样情况
check_res <- result_sample %>%
  group_by(var) %>%
  summarise(actual_n = n()) %>%
  left_join(sample_plan %>% select(var, target_n), by = "var") %>%
  mutate(is_match = actual_n == target_n)

# 校验1:是否覆盖全部44个分组
nrow(check_res) # 返回44即为覆盖全部分组
# 校验2:所有组实际抽样量是否和目标Ni完全一致
all(check_res$is_match) # 返回TRUE即为完全匹配
# 校验3:总样本量是否符合预期
sum(check_res$actual_n) # 返回值和sum(sample_plan$target_n)完全相等

以你提供的示例数据为例,r组仅2条观测,原始计算得到的Ni为0,应用强制规则后target_n变为1,最终总样本量为355,且44个组全部被覆盖。


内容的提问来源于stack exchange,提问作者Homer Jay Simpson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:21:18