如何基于预定义配额在tibble中随机拆分类别为子类别
按预定义配额随机拆分Class为Subclass的实现方法
核心思路
先将预定义的拆分规则转换为宽格式(每个Class对应X、Y的分配数量),再对原始数据按Class分组,每组内随机打乱顺序后,根据配额标记对应的Subclass标签。
完整代码实现
library(tidyverse) # 原始数据集 df <- tibble(Class = c(rep("A", 120), rep("B", 200), rep("C", 300)), Values = runif(620)) # 预定义的拆分配额表 df2 <- tibble(Class = c("A", "A", "B", "B", "C", "C"), Subclass = rep(c("X", "Y"), 3), predefined_split = c(47, 73, 126, 74, 101, 199)) # 转换拆分规则为宽格式,便于按Class匹配配额 split_rules <- df2 %>% pivot_wider(names_from = Subclass, values_from = predefined_split) # 执行随机拆分并分配Subclass result_df <- df %>% group_by(Class) %>% # 每组内随机打乱行顺序,保证拆分的随机性 slice_sample(prop = 1) %>% # 根据配额标记Subclass:前X个配额数的行标记为X,剩余为Y mutate(Subclass = case_when( row_number() <= pull(filter(split_rules, Class == cur_group()$Class), X) ~ "X", TRUE ~ "Y" )) %>% ungroup() # 验证拆分结果是否符合预定义配额 result_df %>% count(Class, Subclass)
关键步骤说明
pivot_wider:把长格式的拆分规则转为宽格式,每个Class对应一行,包含X和Y的分配数量,方便后续分组匹配。slice_sample(prop = 1):对每个Class组内的行进行随机重排,确保拆分是完全随机的,避免顺序带来的偏差。case_when + row_number():结合当前组的X配额,给前N行标记为X,剩余行标记为Y,实现精准的数量分配。- 最后用
count函数可以快速验证每个Class下X、Y的数量是否和预定义配额一致。
内容的提问来源于stack exchange,提问作者SiH
相关产品推荐
相关产品推荐

