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

R语言实现从排列表抽样420行使各列数字频率尽可能均等的方法

R语言实现三元组合的约束抽样,保证列频率尽可能均等

核心原理说明

你使用expand.grid(rep(list(1:8), 3))生成的全量三元组合共512行,原始数据中每列的1-8每个数字均匀出现64次。抽取420行时,理论最优频次为每列每个数字出现52或53次(420÷8=52.5,无法实现完全均等,这是当前抽样规模下能达到的最小波动)。

实现方案

方案1:确定性剔除法(无需额外包,可100%复现)

仅需要定向剔除92行,即可精准控制每列频次符合最优分布,完全不需要随机抽样:

library(dplyr)
# 生成全量三元组合
df <- expand.grid(rep(list(1:8), 3))
# 需要剔除的行数
n_remove <- 92
df$remove_flag <- 0

# 定向剔除,优先剔除三列计数冗余最高的行
while (sum(df$remove_flag) < n_remove) {
  # 统计当前各列每个数字的保留量
  cnt1 <- table(df$Var1[df$remove_flag == 0])
  cnt2 <- table(df$Var2[df$remove_flag == 0])
  cnt3 <- table(df$Var3[df$remove_flag == 0])
  # 筛选待剔除的目标行
  del_row <- df %>%
    filter(remove_flag == 0) %>%
    mutate(
      w1 = cnt1[as.character(Var1)],
      w2 = cnt2[as.character(Var2)],
      w3 = cnt3[as.character(Var3)],
      total_weight = w1 + w2 + w3
    ) %>%
    arrange(desc(total_weight)) %>%
    slice(1)
  # 标记剔除
  df$remove_flag[df$Var1 == del_row$Var1 & df$Var2 == del_row$Var2 & df$Var3 == del_row$Var3] <- 1
}

# 提取最终结果
result_df <- df %>% filter(remove_flag == 0) %>% select(-remove_flag)

方案2:平衡抽样法(使用工具包快速实现)

如果接受极小波动,可使用sampling包的平衡抽样算法一步实现:

library(sampling)
library(dplyr)

df <- expand.grid(rep(list(1:8), 3))
n_sample <- 420
# 构造列平衡的辅助变量
aux_mat <- model.matrix(~ Var1 + Var2 + Var3 - 1, data = df)
# 执行平衡抽样
sample_mask <- sampling::cube(aux_mat, n = n_sample, method = "srswor")
# 提取结果
result_df <- df[as.logical(sample_mask), ]

结果验证

执行以下代码即可确认每列的频次分布:

# 查看三列的数字出现频次
table(result_df$Var1)
table(result_df$Var2)
table(result_df$Var3)

正常输出中所有数字的出现次数仅在52和53之间,为当前场景下的最均匀分布。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 13:12:02