if_else与ifelse处理NA的行为差异:为何前者出现警告?
为什么if_else和ifelse在全NA组汇总时行为不同?
我有一个包含double类型列的tibble,按组汇总时部分组仅包含NA值。构造示例如下:
tibble(x = c(1, NA, NA)) %>% filter(row_number()>1) %>% summarize(x = if_else(!all(is.na(x)), max(x, na.rm = T), NA_real_))
执行后输出正确,但会触发max函数的警告(提示“无非缺失参数返回-Inf”);而改用ifelse时无警告:
tibble(x = c(1, NA, NA)) %>% filter(row_number()>1) %>% summarize(x = ifelse(!all(is.na(x)), max(x, na.rm = T), NA_real_))
两者行为差异的核心原因是求值逻辑不同:
- if_else是严格求值:它会先计算所有分支的表达式,再根据条件选择结果。在这个全NA的组里,即使
!all(is.na(x))为FALSE,max(x, na.rm = T)依然会被执行,此时因为所有值都是NA,max返回-Inf并触发警告,虽然最终if_else会返回NA_real_,但警告已经产生。 - ifelse是惰性求值:它会根据条件的结果,只执行对应分支的代码。当
!all(is.na(x))为FALSE时,只会返回NA_real_,不会去执行max(x, na.rm = T),因此不会触发警告。
另外,if_else还要求两个分支的结果类型、长度完全一致,而ifelse会自动做类型转换,不过这不是本次场景差异的关键。
内容的提问来源于stack exchange,提问作者RandomMonitor
相关产品推荐
相关产品推荐

