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

R语言组内子组各类型等数量抽样失败:问题排查与修正

问题:分组下的等量抽样失败排查与修正

数据集与需求

我有一份按group(组)、subgroup(子组)、type(类型)划分的数据集,模拟代码如下:

data <- data.frame(group    = sample(c(1:30),    10000, replace = TRUE),
                   subgroup = sample(c(1:100),   10000, replace = TRUE),
                   type     = sample(c("A", "B"), 10000, replace = TRUE),
                   value    = sample(c(1:100),    10000, replace = TRUE))

需求是:在每个group+subgroup组合下,对type A和type B抽取等量样本,同时剔除group+subgroup+type组合中无数据(N=0)的情况。

我的尝试与问题

第一步:计算抽样量

library(tidyverse)

n_to_sample <- data %>%
  group_by(group, subgroup, type) %>% 
  summarise(n = n()) %>%
  pivot_wider(id_cols = c("group", "subgroup"),
              names_from =  "type",
              values_from = "n") %>%
  rowwise() %>%
  mutate(lowestN = min(A, B)) %>%
  ungroup() %>% 
  filter(!is.na(lowestN)) %>%
  select (group, subgroup, lowestN)

第二步:执行抽样

data_sampled <- data %>%
  left_join(n_to_sample, by = c("group", "subgroup")) %>% 
  filter(!is.na(lowestN)) %>%
  arrange(group, type) %>%
  filter(row_number() %in% c(sample(which(type == "A"), mean(lowestN)),
                             sample(which(type == "B"), mean(lowestN))),
         .by = c("group", "subgroup")) 

验证代码与问题

我用以下代码验证抽样结果:

data %>%
  count(group, type, subgroup) %>%
  arrange(group, subgroup, type) %>%
  pivot_wider(id_cols = c("group", "subgroup"),
              names_from =  "type",
              values_from = "n")

结果显示计数变量存在大量NA,说明抽样方案未成功。


错误分析与修正方案

核心错误点

  1. 验证对象错误:你用原数据集data而非抽样后的data_sampled做验证,原数据本身就存在group+subgroup下仅包含A或仅包含B的情况,自然会出现NA,这不是抽样逻辑的问题。
  2. 抽样量计算错误:使用mean(lowestN)会取所有组的抽样量均值,而非当前group+subgroup组合对应的lowestN,导致抽样数量不符合需求。
  3. 抽样逻辑混乱:row_number() %in% sample(which(type == "A"), ...)的写法在分组内逻辑冲突,row_number()是整个group+subgroup组的行号,which(type == "A")是组内type为A的行位置,两者混用会导致抽样范围错误。

修正后的完整代码

步骤1:重新计算抽样量(简化逻辑)

n_to_sample <- data %>%
  count(group, subgroup, type) %>%
  pivot_wider(id_cols = c(group, subgroup),
              names_from = type,
              values_from = n) %>%
  filter(!is.na(A) & !is.na(B)) %>% # 直接过滤掉A/B缺失的组合
  rowwise() %>%
  mutate(lowestN = min(A, B)) %>%
  ungroup() %>%
  select(group, subgroup, lowestN)

步骤2:正确执行抽样

data_sampled <- data %>%
  inner_join(n_to_sample, by = c("group", "subgroup")) %>% # 内连接自动过滤不符合的组合
  group_by(group, subgroup, type) %>%
  slice_sample(n = first(lowestN)) %>% # 每个分组抽取对应数量的样本
  ungroup()

正确的验证代码

# 验证每个group+subgroup下A和B的抽样数量是否相等
data_sampled %>%
  count(group, subgroup, type) %>%
  pivot_wider(id_cols = c(group, subgroup),
              names_from = type,
              values_from = n) %>%
  filter(A != B) # 结果为空则说明抽样正确

修正逻辑说明

  • 用inner_join替代left_join+filter,直接排除掉A/B缺失的group+subgroup组合,避免NA干扰。
  • 用slice_sample按group+subgroup+type分组抽样,逻辑更清晰,直接调用当前组的lowestN作为抽样数量。
  • 验证时必须使用抽样后的data_sampled,才能准确检查抽样结果是否符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:35:05