如何将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
相关产品推荐
相关产品推荐

