如何用dplyr的if_any实现:列存在时求值,不存在返回FALSE?
解决dplyr中if_any在目标列不存在时返回FALSE的需求
简洁方案(dplyr 1.1.0+)
从dplyr 1.1.0版本开始,if_any()新增了.default参数,专门用来处理没有匹配到任何目标列的场景,直接指定此时的返回值即可满足你的需求:
library(dplyr) dat <- data.frame(x = 1) # 核心代码 dat %>% mutate(present = if_any(matches("foo_col"), ~ !is.na(.x), .default = FALSE))
验证所有测试场景
- foo_col为NA时
dat %>% mutate(foo_col = NA_character_) %>% mutate(present = if_any(matches("foo_col"), ~ !is.na(.x), .default = FALSE)) #> x foo_col present #> 1 1 <NA> FALSE
符合预期,返回FALSE。
- foo_col非NA时
dat %>% mutate(foo_col = "value") %>% mutate(present = if_any(matches("foo_col"), ~ !is.na(.x), .default = FALSE)) #> x foo_col present #> 1 1 value TRUE
符合预期,返回TRUE。
- foo_col不存在时
dat %>% mutate(present = if_any(matches("foo_col"), ~ !is.na(.x), .default = FALSE)) #> x present #> 1 1 FALSE
符合预期,返回FALSE。
兼容旧版本dplyr的方案
如果你的dplyr版本低于1.1.0,可以先手动检查目标列是否存在,再分支处理:
dat %>% mutate(present = case_when( # 先检查列名是否匹配 any(grepl("foo_col", names(.))) ~ if_any(matches("foo_col"), ~ !is.na(.x)), # 列不存在时返回FALSE TRUE ~ FALSE ))
或者用更直观的if分支:
dat %>% mutate(present = if (any(grepl("foo_col", names(.)))) { if_any(matches("foo_col"), ~ !is.na(.x)) } else { FALSE })
内容的提问来源于stack exchange,提问作者boshek
相关产品推荐
相关产品推荐

