R语言:基于多列数据的分组标记需求实现
按指定规则为DataFrame生成分组列
需求概述
基于现有DataFrame的col1、col2、col3三列,为entity列分配分组并新增Group_col1、Group_col2、Group_col3三列,规则如下:
- 分组固定为6组,标记为5、4、3、2、1、0
- 每列分组逻辑:
- 计算该列的中位数(mid)
- 列值大于mid的项,分组标记为
0 - 列值小于mid的项,划分为5组:值最低的标记为
5,依次递减至1
原始数据
structure(list(entity = c("a", "s", "d", "f", "g", "h", "j", "k", "l", "q", "w", "e", "r", "t", "y", "z", "x", "c", "v", "b" ), col1 = c(18, 27, 28, 50, 42, 18, 18, 39, 16, 49, 42, 26, 18, 38, 15, 50, 18, 10, 36, 22), col2 = c(110, 111, 159, 128, 113, 123, 128, 122, 167, 167, 113, 185, 129, 104, 180, 123, 152, 111, 117, 115), col3 = c(85, 69, 64, 96, 55, 99, 73, 55, 50, 62, 66, 87, 77, 77, 53, 60, 96, 82, 100, 55)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -20L))
解决方案代码
使用dplyr包实现分组逻辑,通过自定义函数批量处理目标列:
library(dplyr) # 加载数据 df <- structure(list(entity = c("a", "s", "d", "f", "g", "h", "j", "k", "l", "q", "w", "e", "r", "t", "y", "z", "x", "c", "v", "b" ), col1 = c(18, 27, 28, 50, 42, 18, 18, 39, 16, 49, 42, 26, 18, 38, 15, 50, 18, 10, 36, 22), col2 = c(110, 111, 159, 128, 113, 123, 128, 122, 167, 167, 113, 185, 129, 104, 180, 123, 152, 111, 117, 115), col3 = c(85, 69, 64, 96, 55, 99, 73, 55, 50, 62, 66, 87, 77, 77, 53, 60, 96, 82, 100, 55)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -20L)) # 定义分组函数 assign_group <- function(x) { mid <- median(x) # 处理小于中位数的数值,分成5组并标记5-1 lower_vals <- x[x < mid] lower_groups <- cut(lower_vals, breaks = 5, labels = 5:1) # 生成最终分组向量 res <- rep(0, length(x)) res[x < mid] <- as.integer(lower_groups) res } # 批量应用分组函数到目标列 df_result <- df %>% mutate(across(c(col1, col2, col3), ~assign_group(.), .names = "Group_{.col}")) # 查看结果 print(df_result)
运行结果
| entity | col1 | col2 | col3 | Group_col1 | Group_col2 | Group_col3 |
|---|---|---|---|---|---|---|
| a | 18 | 110 | 85 | 3 | 3 | 0 |
| s | 27 | 111 | 69 | 1 | 2 | 1 |
| d | 28 | 159 | 64 | 1 | 0 | 2 |
| f | 50 | 128 | 96 | 0 | 0 | 0 |
| g | 42 | 113 | 55 | 0 | 1 | 4 |
| h | 18 | 123 | 99 | 3 | 0 | 0 |
| j | 18 | 128 | 73 | 3 | 0 | 0 |
| k | 39 | 122 | 55 | 0 | 0 | 4 |
| l | 16 | 167 | 50 | 4 | 0 | 5 |
| q | 49 | 167 | 62 | 0 | 0 | 3 |
| w | 42 | 113 | 66 | 0 | 1 | 2 |
| e | 26 | 185 | 87 | 2 | 0 | 0 |
| r | 18 | 129 | 77 | 3 | 0 | 0 |
| t | 38 | 104 | 77 | 0 | 5 | 0 |
| y | 15 | 180 | 53 | 5 | 0 | 5 |
| z | 50 | 123 | 60 | 0 | 0 | 3 |
| x | 18 | 152 | 96 | 3 | 0 | 0 |
| c | 10 | 111 | 82 | 5 | 2 | 0 |
| v | 36 | 117 | 100 | 0 | 0 | 0 |
| b | 22 | 115 | 55 | 2 | 0 | 4 |
内容的提问来源于stack exchange,提问作者CodeMaster
相关产品推荐
相关产品推荐

