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

R语言按指定factor列无重复抽样将dataframe分为4个等规模组

解决方案

核心思路

你的需求核心有两个约束:

  1. 200行全量划分为4组,每组50行
  2. 单个组内factor水平无重复,每个factor水平最多在同一组出现1次

实现逻辑如下:

  • 利用你提到的「每个factor水平最多对应4条观测」的特性,先按factor水平分组,给每个水平下的所有观测分配互不重复的组号(组号取值1-4),这一步天然保证同个factor不会出现在同一个组内
  • 初始分配完成后,如果各组样本量存在偏差,只需将超额组的行调整到缺口组,调整时确保转移的factor水平不在缺口组中存在即可,总样本量200刚好对应4组各50行,必然存在可行的调整方案

实现代码

以下是基于dplyr的可运行实现:

library(dplyr)

set.seed(123) # 固定随机种子保证结果可复现

# 1. 初始分配组号,保证同factor不同组
df_with_group <- df %>%
  group_by(factor) %>%
  mutate(
    # 每个factor下的观测分配互不重复的组号
    group = sample(1:4, size = n(), replace = FALSE)
  ) %>%
  ungroup()

# 2. 调整组大小到每组50行
group_cnt <- table(df_with_group$group)
over_g <- as.numeric(names(group_cnt[group_cnt > 50]))
under_g <- as.numeric(names(group_cnt[group_cnt < 50]))

while (length(under_g) > 0) {
  # 取第一个超额组和第一个缺口组
  current_over <- over_g[1]
  current_under <- under_g[1]
  
  # 筛选可转移的行:所属factor不在缺口组中存在
  transfer_row <- df_with_group %>%
    filter(group == current_over) %>%
    filter(!factor %in% df_with_group$factor[df_with_group$group == current_under]) %>%
    slice_sample(n = 1)
  
  # 变更组号
  row_idx <- which(
    df_with_group$factor == transfer_row$factor &
    df_with_group$y == transfer_row$y &
    df_with_group$x == transfer_row$x
  )
  df_with_group$group[row_idx] <- current_under
  
  # 更新计数
  group_cnt[as.character(current_over)] <- group_cnt[as.character(current_over)] - 1
  group_cnt[as.character(current_under)] <- group_cnt[as.character(current_under)] + 1
  
  # 已达标的组从列表中移除
  if (group_cnt[as.character(current_over)] == 50) over_g <- over_g[-1]
  if (group_cnt[as.character(current_under)] == 50) under_g <- under_g[-1]
}

结果校验

运行以下代码确认符合要求:

# 校验每组样本量为50
print(table(df_with_group$group))

# 校验每组内无重复factor
dup_check <- df_with_group %>%
  group_by(group) %>%
  summarise(has_dup = any(duplicated(factor)))
print(dup_check)

所有has_dup值都为FALSE且每组行数为50即代表符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:54:05