使用case_when实现多级取值逻辑时的异常问题求助
问题:case_when生成变量B时无法正确取A3值的原因与解决方法
样本数据
A1<-seq(3,5); A2<-seq(1,5); A3<-seq(2,8) length(A1)<-7; length(A2)<-7; length(A3)<-7 adf <-as.data.frame(cbind(A1,A2,A3))
生成的数据框如下:
A1 A2 A3 1 3 1 2 2 4 2 3 3 5 3 4 4 NA 4 5 5 NA 5 6 6 NA NA 7 7 NA NA 8
需求
创建新变量B,取值优先级为:优先取A1的值;若A1为缺失值,则取A2的值;若A2也为缺失值,则取A3的值。
尝试的代码及问题
用户尝试了以下case_when代码:
adf %>% mutate( B = case_when( !is.na(A1) ~ A1, is.na(A1) ~ A2, (is.na(A1) & is.na(A2) & !is.na(A3)) ~ A3 ) )
运行结果显示,当A1和A2均缺失、A3非缺失时,B返回NA:
A1 A2 A3 B 1 3 1 2 3 2 4 2 3 4 3 5 3 4 5 4 NA 4 5 4 5 NA 5 6 5 6 NA NA 7 NA 7 NA NA 8 NA
问题原因
case_when的判断逻辑是从上到下依次匹配,一旦满足某个条件就返回对应值,后续条件不再执行。
- 第二个条件
is.na(A1) ~ A2会匹配所有A1缺失的行,包括A2也缺失的行,此时返回A2的NA值,第三个条件根本没有机会被触发。
解决方法
方法1:调整case_when的条件顺序
把最严格的条件(A1和A2都缺失)放在最前面,再依次判断其他情况:
adf %>% mutate( B = case_when( is.na(A1) & is.na(A2) ~ A3, is.na(A1) ~ A2, TRUE ~ A1 # 所有不满足前两个条件的情况,即A1非缺失 ) )
方法2:使用coalesce函数(更简洁)
dplyr的coalesce()函数专门用于按顺序返回第一个非缺失值,完美匹配需求:
library(dplyr) adf %>% mutate(B = coalesce(A1, A2, A3))
两种方法都能得到正确结果:
A1 A2 A3 B 1 3 1 2 3 2 4 2 3 4 3 5 3 4 5 4 NA 4 5 4 5 NA 5 6 5 6 NA NA 7 7 7 NA NA 8 8
内容的提问来源于stack exchange,提问作者Addison
相关产品推荐
相关产品推荐

