在R中基于多条件替换长格式数据框中因子变量的层级
R语言实现按规则生成新分类变量
问题描述
现有长格式数据框,包含ID列和分类变量Category(层级为stage 2、stage 1、elevated、normal),需为每个ID生成新变量New.Category,规则如下:
- 若同一ID存在≥2个连续的
stage 2,则New.Category为stage 2 - 不满足上述条件,但存在≥2个连续的
stage 1,则为stage 1 - 不满足上述条件,但存在≥2个连续的
elevated,则为elevated - 不满足上述条件,但存在≥2个连续的
normal,则为normal - 无连续重复层级时,取出现频率最高的层级
- 若所有层级各出现一次,取优先级最高的(优先级:
stage 2>stage 1>elevated>normal)
示例数据
ID <- c(3, 3, 3, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10) Category <- c("elevated", "elevated", "stage 2", "stage 1", "normal", "normal", "stage 1", "stage 1", "stage 1", "stage 2", "stage 2", "elevated", "stage 1", "elevated", "stage 1", "elevated", "stage 2", "stage 1", "elevated") df1 <- data.frame(ID, Category)
解决方案
使用dplyr和data.table包实现,核心逻辑是先识别连续重复的分组,再按规则依次判断:
library(dplyr) library(data.table) # 定义层级优先级顺序 priority_order <- c("stage 2", "stage 1", "elevated", "normal") # 处理数据并生成New.Category df_result <- df1 %>% # 将Category转为有序因子,方便后续优先级判断 mutate(Category = factor(Category, levels = priority_order, ordered = TRUE)) %>% group_by(ID) %>% mutate( # 标记连续相同的Category分组ID group_id = rleid(Category), # 计算每个连续分组的长度 group_len = n() ) %>% # 按ID汇总关键信息 summarise( # 检查各层级是否存在连续≥2的情况 has_stage2 = any(Category == "stage 2" & group_len >= 2), has_stage1 = any(Category == "stage 1" & group_len >= 2), has_elevated = any(Category == "elevated" & group_len >= 2), has_normal = any(Category == "normal" & group_len >= 2), # 统计各层级出现频率 cat_freq = table(Category), # 获取频率最高的层级(多频率相同时取优先级最高的) top_freq_cat = names(cat_freq)[which.max(cat_freq)], # 记录当前ID的所有层级 all_categories = list(Category) ) %>% # 按规则生成New.Category mutate( New.Category = case_when( has_stage2 ~ "stage 2", has_stage1 ~ "stage 1", has_elevated ~ "elevated", has_normal ~ "normal", # 检查是否所有层级各出现一次 length(cat_freq) == 4 & all(cat_freq == 1) ~ priority_order[1], # 其余情况取频率最高的层级 TRUE ~ top_freq_cat ) ) %>% # 合并回原数据框,保留所有行 right_join(df1, by = "ID") %>% # 调整列顺序并将Category转回字符型(按需保留因子) select(ID, Category, New.Category) %>% mutate(Category = as.character(Category))
结果验证
查看处理后的结果:
print(df_result)
输出示例:
ID Category New.Category 1 3 elevated elevated 2 3 elevated elevated 3 3 stage 2 elevated 4 6 stage 1 normal 5 6 normal normal 6 6 normal normal 7 7 stage 1 stage 1 8 7 stage 1 stage 1 9 7 stage 1 stage 1 10 8 stage 2 stage 2 11 8 stage 2 stage 2 12 8 elevated stage 2 13 9 stage 1 stage 1 14 9 elevated stage 1 15 9 stage 1 stage 1 16 9 elevated stage 1 17 10 stage 2 stage 2 18 10 stage 1 stage 2 19 10 elevated stage 2
各ID的判断逻辑:
- ID3:存在连续2个
elevated,符合规则3 - ID6:存在连续2个
normal,符合规则4 - ID7:存在连续3个
stage 1,符合规则2 - ID8:存在连续2个
stage 2,符合规则1 - ID9:无连续重复层级,
stage 1和elevated各出现2次,按优先级取stage 1(规则5) - ID10:三个层级各出现一次,取最高优先级
stage 2(规则6)
内容的提问来源于stack exchange,提问作者19056530
相关产品推荐
相关产品推荐

