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

R中无放回随机抽样避错:按条件抽取5%行的实现问题

问题解决:分组随机抽样报错处理

需求

  • 按speaker和lang过滤数据后,对每个child_id分组做无放回抽样:
    • 若分组行数≤4,直接跳过该分组;
    • 若分组行数≥5,抽取该分组行数的5%(至少1行);
  • 最终汇总所有抽取的行组成表格。

报错信息

Error in `sample_n()`:
! Can't compute indices.
ℹ In group 1: `child_id = 112`.
Caused by error:
! `size` must be less than or equal to 159 (size of data).
ℹ set `replace = TRUE` to use sampling with replacement.

原代码

set.seed(123)
random_all_speakers_10 <- data.frame()
speakers <- c("Mom", "Dad", "Other", "Multiple")
languages <- c("Fr", "Eng")

for (speaker in speakers) {
    for (lang in languages) {
       filtered_data <- data_10_coded_collapsed %>%
           filter(spkr == speaker, lang == lang)
        if (nrow(filtered_data) > 4) {
            num_to_sample <- max(1, round(nrow(filtered_data) * 0.05))
            
            if (num_to_sample >= nrow(filtered_data)) {
                sampled_data <- filtered_data
            } else {
                sampled_data <- filtered_data %>%
                    group_by(child_id) %>%
                    sample_n(size = num_to_sample, replace = FALSE)
            }
            random_all_speakers_10 <- bind_rows(random_all_speakers_10, sampled_data)
        }
    }
}

问题原因

原代码核心错误:用整个过滤后数据集的行数计算抽样数量,强制每个child_id分组都抽取该固定数量。当某个分组的行数小于这个全局抽样数时,无放回抽样无法执行,直接触发报错。

比如:整个filtered_data有3180行,计算出num_to_sample=159,但某个child_id分组只有100行,此时要求抽取159行超出了分组行数上限。

修正后的代码

set.seed(123)
random_all_speakers_10 <- data.frame()
speakers <- c("Mom", "Dad", "Other", "Multiple")
languages <- c("Fr", "Eng")

for (speaker in speakers) {
  for (lang in languages) {
    filtered_data <- data_10_coded_collapsed %>%
      filter(spkr == speaker, lang == lang)
    
    if (nrow(filtered_data) > 4) {
      sampled_data <- filtered_data %>%
        group_by(child_id) %>%
        filter(n() > 4) %>% # 跳过行数≤4的分组
        slice_sample(n = max(1, round(n() * 0.05)), replace = FALSE) %>% # 每个分组单独计算抽样数
        ungroup()
      
      random_all_speakers_10 <- bind_rows(random_all_speakers_10, sampled_data)
    }
  }
}

关键改动说明

  1. 移除全局抽样数计算:改为在每个child_id分组内,用n()获取当前分组行数,单独计算抽样数量;
  2. 提前过滤无效分组:通过filter(n() > 4)直接筛掉行数不足5的分组,符合需求中的跳过规则;
  3. 使用slice_sample替代sample_n:sample_n已被官方弃用,slice_sample是更推荐的抽样函数,语法更清晰;
  4. 保证抽样合理性:max(1, round(n() * 0.05))确保每个有效分组至少抽取1行,且抽样数不会超过分组行数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:00:31