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

如何用dplyr实现分位数内等大小随机子组分配?

解决方案:分位数组内的均匀随机子组分配

这个问题的核心是要在每个分位数组内部实现子组的均匀随机分配,而不是全局随机采样——后者自然会导致分布不均。这里有个适配任意分位数/子组数量、完全兼容dplyr管道的优雅方案:

实现代码

library(dplyr)

# 构造示例数据
df <- structure(list(id = 1:300, value = runif(300, 20000, 100000)), 
                class = "data.frame", row.names = c(NA, -300L))

groups <- 5
subgroups <- 3
set.seed(30)

result.df <- df %>%
  # 第一步:按value划分分位数组
  mutate(group = ntile(value, n = groups)) %>%
  # 第二步:按分位数组分组,在组内分配均匀随机的子组
  group_by(group) %>%
  mutate(
    subgroup = sample(
      # 生成均匀分配的子组序列:先分配基础均等数量,再处理余数
      c(rep(1:subgroups, each = n() %/% subgroups),
        rep(1:(n() %% subgroups), each = 1)),
      # 打乱顺序实现随机化
      size = n(),
      replace = FALSE
    )
  ) %>%
  # 取消分组(可选,根据后续操作需求)
  ungroup()

代码逻辑说明

  1. 分位数组划分:用ntile完成基础的分位数分组,这个和你原来的逻辑一致。
  2. 组内均匀分配:
    • 对每个分位数组,先计算每个子组的基础大小:n() %/% subgroups(总组数除以子组数的整数部分)。
    • 如果组内行数不能被子组数整除,把剩余的行依次分配给前几个子组(每个多1行),用rep(1:(n() %% subgroups), each = 1)实现。
    • 最后用sample打乱这个均匀序列,保证子组分配是随机的,但数量严格均等(或仅差1行)。

验证结果

运行table(result.df$group, result.df$subgroup),你会得到完全均匀的分布:

1  2  3
  1 20 20 20
  2 20 20 20
  3 20 20 20
  4 20 20 20
  5 20 20 20

(如果你的数据行数不是完美的倍数,比如301行,那么部分子组会是21行,其余是20行,依然是最均等的分配)

通用性说明

这个方案完全适配任意正整数的groups和subgroups参数:不管分位数组数量、子组数量是多少,都会自动计算每个组内的最优子组大小,同时保持随机性。

内容的提问来源于stack exchange,提问作者Lorcán

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:58:18