使用dplyr的case_when基于多变量时出现错误求助
R包更新后dplyr::case_when多变量条件判断报错问题
全局更新R包后,原本正常运行的R Markdown文档中,使用dplyr的case_when基于多变量做条件判断时出现无法解读的错误。单独针对what或how变量执行case_when都能正常运行,但两次操作会覆盖结果;添加TRUE默认分支也会引发错误,而官方文档明确支持多变量条件分支。
基础示例代码(可正常运行)
case_character_type <- function(height, mass, species) { case_when( height > 200 | mass > 200 ~ "large", species == "Droid" ~ "robot", TRUE ~ "other" ) } case_character_type(150, 250, "Droid") #> [1] "large" case_character_type(150, 150, "Droid") #> [1] "robot"
报错复现代码
exp <- structure(list(exercise_tf = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), how = c("walk", "bike", "bike", "drive", "walk", "bike", "bike", "drive_train", "drive", "drive_train"), time_commute_min = c(10, 25, 30, 15, 10, 25, 30, 26, 20, 26), what = c("to bjj", "to work", "home from work", "to f3", "to bjj", "to work", "home from work", "to bjj", "to f3", "to bjj")), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame")) # 单独运行正常 exp %>% mutate(ex_time = case_when(grepl("bike", how) ~ time_commute_min)) # 单独运行正常 exp %>% mutate(ex_time = case_when(grepl("to bjj", what) ~ 45L, grepl("to f3", what) ~ 45L)) # 合并运行报错 exp %>% filter(exercise_tf) %>% mutate(ex_time = case_when( grepl("bike", how) ~ time_commute_min, grepl("to bjj", what) ~ 45L, grepl("to f3", what) ~ 45L ) )
报错信息
Error in
mutate():
! Problem while computingex_time = case_when(...).
Caused by error incase_when():Backtrace:
- exp %>% filter(exercise_tf) %>% ...
- dplyr::case_when(...)
Error in mutate(., ex_time = case_when(grepl("bike", how) ~ time_commute_min, :Caused by error in
case_when():
问题原因
报错核心是**case_when各分支返回值的类型不匹配**:
time_commute_min是numeric(数值型)45L是integer(整数型)
dplyr更新后对case_when的类型一致性检查更严格,不同类型的返回值会触发报错。单独运行时单个分支类型统一,所以没问题;合并后分支返回类型混杂,就会报错。添加默认分支如果类型不统一,同样会触发错误。
修复方案
只需将所有分支的返回值统一为相同类型即可,两种可选方式:
方式1:将数值型转为整数型
exp %>% filter(exercise_tf) %>% mutate(ex_time = case_when( grepl("bike", how) ~ as.integer(time_commute_min), grepl("to bjj", what) ~ 45L, grepl("to f3", what) ~ 45L ) )
方式2:将整数型转为数值型
exp %>% filter(exercise_tf) %>% mutate(ex_time = case_when( grepl("bike", how) ~ time_commute_min, grepl("to bjj", what) ~ 45, grepl("to f3", what) ~ 45 ) )
补充:添加默认分支
建议统一类型后添加默认分支,避免未匹配情况:
exp %>% filter(exercise_tf) %>% mutate(ex_time = case_when( grepl("bike", how) ~ time_commute_min, grepl("to bjj", what) ~ 45, grepl("to f3", what) ~ 45, TRUE ~ NA_real_ # 与数值型返回值匹配的NA ) )
内容的提问来源于stack exchange,提问作者captaincaed
相关产品推荐
相关产品推荐

