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

按分组变量实现数据集变数量抽样的报错问题求助

按分组变量动态抽样的问题及解决方案

需求:根据数据集分组内的指定变量,对每个组抽取对应数量的样本。

原始代码与报错

最初使用的代码在旧版本dplyr中可运行,但当前版本报错:

data <- data.frame(id = seq(1, 10000), group = sample(c(1:3), 100, replace = TRUE))
data <- data %>% mutate(n = group*2)
data <- data %>% group_by(group) %>% do(sample_n(., n))

报错信息:

Error in `sample_n()`:
! Can't compute indices.
Caused by error in `size <= n || replace`:
! 'length = 3800' in coercion to 'logical(1)'
Run `rlang::last_trace()` to see where the error occurred.

尝试的替代方法及新问题

尝试使用slice_sample替代sample_n,在小数据集(甚至200万行)中可行:

data <- data.frame(id = seq(1, 2000000), group = sample(c(1:10000), 2000000, replace = TRUE))
data <- data %>% mutate(n = group*2)
data <- data %>% group_by(group) %>% do(slice_sample(., n=unique(.$n)))

但处理实际大数据集(行数超过223000)时触发新错误:

test <- bano_tirage[c(100000:3240000),]
bano_sample <- test %>% group_by(nom_commune) %>% group_modify(~ slice_sample(.x, n = unique(.x$pop_contact)))

报错信息:

Error in `slice_sample()`:
! `n` must be a round number, not an integer vector.
Run `rlang::last_trace()` to see where the error occurred.

有效解决方案

方案1:dplyr优化版(处理向量与边界问题)

问题根源是部分分组内的pop_contact并非单一值,导致unique(.x$pop_contact)返回向量,同时未处理抽样数量超过组内行数的情况。优化代码如下:

bano_sample <- test %>%
  group_by(nom_commune) %>%
  group_modify(~ {
    # 取组内第一个pop_contact值作为抽样数量,确保为单值
    sample_size <- first(.x$pop_contact)
    # 避免抽样数量超过组内实际行数,可选replace=TRUE允许重复抽样
    slice_sample(.x, n = min(sample_size, nrow(.x)), replace = FALSE)
  }) %>%
  ungroup()

方案2:data.table高效版(适合超大数据集)

data.table的分组操作效率远高于dplyr::group_modify,更适合百万级以上数据集:

library(data.table)
setDT(test)

bano_sample <- test[, .SD[sample(.N, min(first(pop_contact), .N))], by = nom_commune]

关键说明:

  • first(pop_contact):确保每个分组仅取一个抽样数量,避免向量输入报错
  • min(sample_size, .N):当抽样数量大于组内行数时,自动取组内所有样本,也可根据需求设置replace=TRUE启用重复抽样
  • data.table的.SD代表当前分组的子数据集,sample(.N, ...)直接对子集行号抽样,性能更优

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:05:23