R语言按ID统计唯一年份组合出现频次的实现方法
错误原因
之前三种方法无法得到正确结果,核心是两个逻辑漏项:
- 未对单ID下的重复年份去重:同一患者同一年多次就诊的记录会被重复拼接,导致组合字符串出现重复年份
- 未对单ID对应的年份做排序:同一组合如果年份拼接顺序不同(比如
2011,2010和2010,2011)会被判定为不同类别,直接导致统计结果拆分错误
另外你初始化的years向量里没有2012,实际不会出现包含2012的年份组合,总理论组合数确实是2^5=32种。
正确实现方案
方案1:dplyr 实现(直接修正原方法3的逻辑漏洞)
library(dplyr) library(stringr) final <- my_data %>% group_by(id) %>% # 核心步骤:先对每个ID的年份去重、排序后再拼接,保证同一种组合的字符串完全一致 summarise(combinations = str_c(sort(unique(year)), collapse = ","), .groups = "drop") %>% count(combinations, name = "frequency") # 如果需要补全全部32种理论存在、但实际可能无对应患者的0频次组合,追加以下代码 all_combos <- unlist( lapply(1:length(years), function(k) combn(sort(years), k, paste, collapse = ",")), use.names = FALSE ) final <- tibble(combinations = all_combos) %>% left_join(final, by = "combinations") %>% mutate(frequency = tidyr::replace_na(frequency, 0))
方案2:data.table 实现
library(data.table) setDT(my_data) final <- my_data[, .(combinations = paste(sort(unique(year)), collapse = ",")), by = id ][, .(frequency = .N), by = combinations ]
方案3:基础R实现(无需加载第三方包)
# 按ID拆分数据,对每个患者的就诊年份去重排序后拼接 patient_combos <- tapply(my_data$year, my_data$id, function(x) paste(sort(unique(x)), collapse = ",")) # 统计各组合频次 final <- data.frame( combinations = names(table(patient_combos)), frequency = as.vector(table(patient_combos)) )
输出格式说明
运行后得到的结果和你给出的示例格式完全一致,列名分别为combinations(年份组合)和frequency(对应患者数),可以直接回答「仅单年份就诊的患者数」「多年份同时就诊的患者数」等统计问题。如果追加了补全0频次的代码,结果会固定包含全部32种可能组合,不会因为某类组合没有对应患者就缺失行。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

