R中case_when()的is.na()条件为何失效?如何修复?
问题原因与修复方案
为什么case_when的条件被跳过?
- R的
case_when()不是短路执行逻辑:所有分支的表达式都会被预先计算,不管前面的条件是否匹配。哪怕你的数据里有行满足is.na(pass)或is.na(total),TRUE分支里的prop.test()依然会被执行,而level="1"组里存在NA值,直接传入prop.test()就会触发报错。 - 条件逻辑不匹配:你写的
is.na(pass)是针对每行的判断,但prop.test()是针对整个分组的计算——每个分组只需要一个p值,但你试图给每行生成这个值,组内只要有一个NA行,就会导致整个组的prop.test()执行失败。
修复方法
方法1:主动检查分组内的NA值,提前返回NA
先判断当前分组里是否存在pass或total的NA值,再决定是否执行比例检验,逻辑更清晰:
library(tidyverse) sample_data <- tibble( subject = c("psych", "math", "psych", "math"), level = c("1", "1", "2", "2"), pass = c(NA_real_, 8, 13, 1), total = c(NA_real_, 102, 195, 36) ) sample_data %>% group_by(level) %>% mutate( sig_dif = if (any(is.na(pass), is.na(total))) { NA_real_ } else { # 先提取分组内的两组数据,避免重复索引 psych_pass <- pass[subject == "psych"] math_pass <- pass[subject == "math"] psych_total <- total[subject == "psych"] math_total <- total[subject == "math"] round(prop.test(c(psych_pass, math_pass), c(psych_total, math_total))$p.value, 3) } ) %>% ungroup()
方法2:用tryCatch捕获错误,出错时返回NA
如果想兼容更多可能的错误(比如样本量不足等),可以用tryCatch()包裹prop.test(),执行出错时直接返回NA:
sample_data %>% group_by(level) %>% mutate( sig_dif = round( tryCatch( prop.test(c(pass[subject == "psych"], pass[subject == "math"]), c(total[subject == "psych"], total[subject == "math"]))$p.value, error = function(e) NA_real_ ), 3 ) ) %>% ungroup()
内容的提问来源于stack exchange,提问作者J.Sabree
相关产品推荐
相关产品推荐

