如何让R语言dplyr的case_when输出符合各条件的行数?
统计dplyr::case_when各条件匹配行数的方法
在使用dplyr::case_when处理多逻辑条件时,由于它按顺序评估匹配,早匹配的条件会覆盖后续符合条件的行,很容易误判某个条件是否实际生效。以下是几种适配case_when语法的方法,用来统计每个条件的匹配行数:
方法1:手动计算每个条件的实际生效行数
直接针对case_when的条件顺序,计算每个条件在前面所有条件不成立时的匹配行数:
mtcars %>% summarize( # 第一个条件:gear ==5 的行数 cond1 = sum(gear == 5), # 第二个条件:gear==4 且未被第一个条件匹配的行数 cond2 = sum(gear == 4 & ! (gear == 5)), # 第三个条件:gear>=3 且未被前两个条件匹配的行数 cond3 = sum(gear >= 3 & ! (gear ==5 | gear ==4)) )
运行后会发现cond3的结果为0,说明这个条件在你的示例中完全没有生效——因为mtcars的gear只有3、4、5三个值,前两个条件已经覆盖了所有gear>=3的情况。
方法2:先标记所有条件的匹配情况,再统计
先给每个条件创建标记列,再分别统计总匹配数和实际生效数:
mtcars %>% mutate( cond1 = gear == 5, cond2 = gear == 4, cond3 = gear >= 3 ) %>% summarize( # 实际生效行数(case_when中真正用到的) cond1_effective = sum(cond1), cond2_effective = sum(cond2 & !cond1), cond3_effective = sum(cond3 & !cond1 & !cond2), # 可选:统计条件本身的总匹配数(不管顺序) cond1_total = sum(cond1), cond2_total = sum(cond2), cond3_total = sum(cond3) )
这种方式能直观对比条件本身的匹配范围和实际生效范围。
方法3:封装工具函数自动统计
如果经常需要做这类统计,可以写一个小函数,自动处理case_when风格的条件列表,输出每个条件的总匹配数和实际生效数:
count_case_when <- function(data, ...) { conds <- rlang::quos(...) matched <- rep(FALSE, nrow(data)) result <- dplyr::tibble( condition = character(), total_matches = integer(), effective_matches = integer() ) for (cond in conds) { cond_match <- data %>% dplyr::pull(!!cond) total <- sum(cond_match, na.rm = TRUE) effective <- sum(cond_match & !matched, na.rm = TRUE) matched <- matched | cond_match result <- result %>% dplyr::add_row( condition = deparse(rlang::get_expr(cond)), total_matches = total, effective_matches = effective ) } result } # 调用示例,对应你的case_when条件 count_case_when(mtcars, gear == 5, gear == 4, gear >= 3 )
运行结果会清晰显示每个条件的情况:
| condition | total_matches | effective_matches |
|---|---|---|
| gear == 5 | 8 | 8 |
| gear == 4 | 12 | 12 |
| gear >= 3 | 32 | 0 |
这样就能快速判断出第三个条件在当前的顺序下没有实际生效。
内容的提问来源于stack exchange,提问作者Arthur Yip
相关产品推荐
相关产品推荐

