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

如何用dplyr的summarise实现分组数据框的条件抽样(无需拆分)

分组抽样:无需拆分数据的高效实现

核心思路

无需将数据拆分为列表再迭代,直接利用dplyr的分组向量化操作,结合slice_sample按组计算抽样数量并完成抽样。抽样数量取组内行数×抽样比例和最小抽样数中的较大值。

代码实现

library(dplyr)

# 构造示例数据
set.seed(123)  # 固定随机种子保证结果可复现
df <- tibble(
  group_id = rep(c("A", "B", "C"), c(30, 8, 4)),  # 三个组,行数分别为30、8、4
  value = rnorm(42)
)

# 定义抽样参数
sample_ratio <- 0.1  # 抽样比例
min_sample_size <- 5  # 最小抽样数

# 高效分组抽样
sampled_data <- df %>%
  group_by(group_id) %>%
  # 按组计算抽样数量:取比例抽样数和最小抽样数的较大值
  slice_sample(n = max(round(n() * sample_ratio), min_sample_size), replace = FALSE) %>%
  ungroup()

关键细节说明

  1. n()的作用:在group_by的上下文里,n()直接返回当前组的行数,无需额外调用cur_data()或cur_group(),避免了作用域冲突。
  2. slice_sample的优势:该函数支持在分组后动态传入抽样数量的表达式,内部基于向量化逻辑处理,比拆分列表后用map/lapply迭代效率更高,尤其适合大数据集。
  3. 如果仅需计算抽样数量:若不需要抽样后的行数据,仅需统计每个组的抽样规模,可使用summarise:
sample_size_stats <- df %>%
  group_by(group_id) %>%
  summarise(
    required_sample_size = max(round(n() * sample_ratio), min_sample_size),
    .groups = "drop"
  )

替代方案(复杂场景)

如果需要对组内数据做更复杂的自定义处理,可使用group_modify结合cur_data():

sampled_data_custom <- df %>%
  group_by(group_id) %>%
  group_modify(function(group_data, group_keys) {
    n_needed <- max(round(nrow(group_data) * sample_ratio), min_sample_size)
    slice_sample(group_data, n = n_needed)
  }) %>%
  ungroup()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:55:20