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

如何将dataframe划分为因子互斥分组,保证同一因子仅归属同一分组

R DataFrame 按因子列无拆分分组解决方案

核心实现逻辑是先为每个唯一的car因子值分配固定组号,再将组号映射回原数据集,从根源上避免同一因子被拆分到多个分组。

方法1:tidyverse 实现(按因子数量均分分组)

该方法适合不同car对应的记录数差异不大的场景,分组逻辑为将唯一car值平均分配到指定数量的分组中:

library(dplyr)

# 示例数据
test = data.frame(car = c("A", "A", "B", "C", "D", "E", "B", "C", "D"), value = c(5,4,3,5, 6, 6, 7 ,8 ,10))

# 1. 为每个唯一car分配分组
car_group <- test %>%
  distinct(car) %>%
  mutate(group = ntile(car, 2)) # 第二个参数为目标分组数,需小于等于唯一car的数量

# 2. 分组匹配回原数据集
test_result <- test %>%
  left_join(car_group, by = "car")

方法2:tidyverse 实现(按记录数均衡分组)

如果不同car对应的记录数差异很大,希望每个分组的总行数尽量接近,可以使用按累计记录数切分的逻辑:

library(dplyr)

car_group <- test %>%
  count(car, name = "row_cnt") %>% # 统计每个car对应的行数
  arrange(desc(row_cnt)) %>% # 大样本量car优先排序,避免分组样本量差异过大
  mutate(cum_cnt = cumsum(row_cnt),
         group = cut(cum_cnt, breaks = 2, labels = FALSE)) # breaks参数为目标分组数

test_result <- test %>%
  left_join(select(car_group, car, group), by = "car")

方法3:基础R 实现

不需要加载第三方包的轻量实现:

# 示例数据
test = data.frame(car = c("A", "A", "B", "C", "D", "E", "B", "C", "D"), value = c(5,4,3,5, 6, 6, 7 ,8 ,10))

# 生成car与组号的映射关系
unique_car <- unique(test$car)
car_group_map <- setNames(ntile(unique_car, 2), unique_car) # 第二个参数为目标分组数

# 映射回原数据
test$group <- car_group_map[test$car]

注意事项

  • 目标分组数不能超过car列的唯一值数量,否则会出现空分组
  • 如果需要每次生成分组的结果完全固定,可以在分配组号前执行set.seed(自定义数值)固定随机种子;如果按字符顺序分配组号则本身就是固定结果,不需要额外设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:36:02