如何在R中避免同一列分组重复统计已出现的EPISODE值?
按有序分类统计首次出现的唯一EPISODE数量
数据背景
已通过cut()函数将PRODUCT_TIME分类为CATEGORY,数据结构如下:
df <- structure(list(EPISODE = c(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4), PRODUCT_TIME = c(1, 2, 1, 1, 2, 3, 4, 4, 5, 6, 8, 10, 1, 2, 1, 5, 8, 2), CATEGORY = c("1", "2", "1", "1", "2", "3 to 5", "3 to 5", "3 to 5", "3 to 5", "6 to 10", "6 to 10", "6 to 10", "1", "2", "1", "3 to 5", "6 to 10", "2")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -18L))
数据预览:
| EPISODE | PRODUCT_TIME | CATEGORY |
|---|---|---|
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 2 | 2 | 2 |
| 2 | 3 | 3 to 5 |
| 2 | 4 | 3 to 5 |
| 2 | 4 | 3 to 5 |
| 3 | 5 | 3 to 5 |
| 3 | 6 | 6 to 10 |
| 4 | 8 | 6 to 10 |
| 4 | 10 | 6 to 10 |
| 4 | 1 | 1 |
| 4 | 2 | 2 |
| 4 | 1 | 1 |
| 4 | 5 | 3 to 5 |
| 4 | 8 | 6 to 10 |
| 4 | 2 | 2 |
CATEGORY为有序变量,顺序为:"1"、"2"、"3 to 5"、"6 to 10"。
需求
- 统计每个
CATEGORY中不同的EPISODE值数量; - 后续分组统计时,排除之前分组中已出现过的
EPISODE值。
解决方案
利用dplyr和purrr包,按有序分类逐步筛选首次出现的EPISODE:
library(dplyr) library(purrr) library(stringr) # 将CATEGORY转为有序因子,保证处理顺序正确 df$CATEGORY <- factor(df$CATEGORY, levels = c("1", "2", "3 to 5", "6 to 10"), ordered = TRUE) # 提取每个分类对应的唯一EPISODE集合 category_episodes <- df %>% group_by(CATEGORY) %>% summarize(episodes = list(unique(EPISODE))) %>% arrange(CATEGORY) # 初始化已出现的EPISODE集合 seen_episodes <- c() # 遍历每个分类,计算新增的唯一EPISODE result <- map_dfr(category_episodes$episodes, function(eps) { new_eps <- setdiff(eps, seen_episodes) # 更新已出现集合 seen_episodes <<- union(seen_episodes, new_eps) tibble( count = length(new_eps), episodes = list(new_eps) ) }) # 合并结果并格式化输出 final_result <- bind_cols(category_episodes, result) %>% mutate( output = case_when( count == 0 ~ str_glue('分组 "{CATEGORY}" = 0个唯一EPISODE值'), count == 1 ~ str_glue('分组 "{CATEGORY}" = 1个唯一EPISODE值 ({episodes[[1]]})'), count >= 2 ~ str_glue('分组 "{CATEGORY}" = {count}个唯一EPISODE值 ({paste(episodes[[1]], collapse = ", ")})') ) ) %>% pull(output) # 打印结果 print(final_result)
运行结果
[1] "分组 \"1\" = 3个唯一EPISODE值 (1, 2, 4)" [2] "分组 \"2\" = 0个唯一EPISODE值" [3] "分组 \"3 to 5\" = 1个唯一EPISODE值 (3)" [4] "分组 \"6 to 10\" = 0个唯一EPISODE值"
内容的提问来源于stack exchange,提问作者Jobolo
相关产品推荐
相关产品推荐

