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

如何在R中按条件打乱dataframe行,保证每3行分组的ClassNr不重复

实现思路

你当前的数据集里每个ClassNr刚好对应2条记录,要实现每3行分组内无重复ClassNr且全量保留原始行,可按以下逻辑实现:

  1. 按ClassNr对数据分组,每组内先做随机打乱
  2. 给每个分组内的行分配组内序号(如2条记录的分组会生成序号1、2)
  3. 按组内序号排序,相同序号的3条记录刚好对应ClassNr1、2、3各1条,自动满足分组去重要求,同组内还可以再做一次随机排序调整顺序

dplyr 实现代码

library(dplyr)

# 示例数据构造
l <- c("Ana", "Maria", "Hanne", "Liam","Sarah","Ella")
c <- c(1,1,2,3,3,2)
df <- as.data.frame(cbind(l,c))
colnames(df) <- c("Name", "ClassNr")

set.seed(55)
df_result <- df %>%
  # 按ClassNr分组,组内随机打乱顺序
  group_by(ClassNr) %>%
  sample_n(n()) %>%
  # 生成组内序号
  mutate(group_id = row_number()) %>%
  ungroup() %>%
  # 按组内序号排序,同序号的为一个分组,同分组内可再随机打乱
  group_by(group_id) %>%
  sample_n(n()) %>%
  ungroup() %>%
  # 去掉辅助列
  select(-group_id)

运行后输出df_result即可得到符合要求的结果,示例运行结果:

Name  ClassNr
  <chr> <chr>  
1 Ana   1      
2 Ella  2      
3 Liam  3      
4 Maria 1      
5 Hanne 2      
6 Sarah 3  

基础R实现(无需加载第三方包)

set.seed(55)
# 按ClassNr拆分数据,每个分组内打乱
split_df <- lapply(split(df, df$ClassNr), function(x) x[sample(nrow(x)), ])
# 给每个分组添加组内序号
split_df <- lapply(split_df, function(x) {
  x$group_id <- seq_len(nrow(x))
  return(x)
})
# 合并所有分组,按group_id排序后同组内打乱
df_combined <- do.call(rbind, split_df)
df_result <- do.call(rbind, lapply(split(df_combined, df_combined$group_id), function(x) x[sample(nrow(x)), ]))
# 去掉辅助列
df_result$group_id <- NULL
# 重置行号
rownames(df_result) <- NULL

两种实现逻辑完全一致,可根据使用习惯选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:27:00