如何将字符向量的每个唯一元素均分为指定数量的分箱?
解决方案
你可以通过分组后生成均匀分箱的方式实现需求,不管用dplyr还是base R都能搞定,以下是两种具体实现:
方法1:用dplyr分组处理
加载dplyr包后,按字符类别分组,在每个组内根据元素数量生成对应分箱编号:
library(dplyr) # 生成原始向量 x <- rep(c("A","B","C"), times=c(6,8,3)) # 生成分箱向量 df <- tibble(x = x) %>% group_by(x) %>% mutate(x_bin = { n <- n() # 获取当前组的元素总数 base <- floor(n / 3) # 每个分箱的基础元素数 extra <- n %% 3 # 无法均分的剩余元素数 # 前extra个分箱各多分配1个元素,剩下的分箱用基础数量 times_vec <- c(rep(base + 1, extra), rep(base, 3 - extra)) rep(1:3, times = times_vec) # 生成重复的分箱编号 }) %>% ungroup() # 查看最终分箱结果 df$x_bin
运行后df$x_bin会输出:1 1 2 2 3 3 1 1 1 2 2 2 3 3 1 2 3,完全匹配你的需求。
方法2:用base R的ave函数(无需额外包)
如果不想加载dplyr,用base R原生的ave函数也能实现:
# 生成原始向量 x <- rep(c("A","B","C"), times=c(6,8,3)) # 生成分箱向量 x_bin <- ave(seq_along(x), x, FUN = function(y) { n <- length(y) base <- floor(n / 3) extra <- n %% 3 times_vec <- c(rep(base + 1, extra), rep(base, 3 - extra)) rep(1:3, times = times_vec) }) # 可选:将结果转为数值型 x_bin <- as.numeric(x_bin)
逻辑说明
核心思路是针对每个字符类别,先统计元素总数n,把n尽可能均匀地分成3份:
- 若
n能被3整除,3个分箱的元素数完全相同; - 若
n无法被3整除,前n%%3个分箱各多分配1个元素,剩下的分箱用基础数量;
最后用rep函数生成对应重复次数的分箱编号即可。
内容的提问来源于stack exchange,提问作者HappyPy
相关产品推荐
相关产品推荐

