dplyr分组条件语句:if_else、ifelse与case_when结果差异及解法问询
分组数据中dplyr条件语句的差异与if_else正确用法
在使用dplyr处理分组数据时,我尝试用三种条件语句实现相同逻辑(组内观测数大于1时保留原始score,否则设为0),但得到了不同结果:
library(dplyr) data("cms_patient_care", package = "tidyr") cms_patient_care2 <- cms_patient_care %>% arrange(ccn, measure_abbr)%>% group_by(ccn, measure_abbr)%>% mutate( score2 = ifelse(n()>1, score, 0), score3 = if_else(n()>1, score, 0), score4 = case_when( n()>1 ~ score, TRUE ~ 0) )%>% ungroup() cms_patient_care2 %>% head(10)
三种函数的表现差异
ifelse:条件满足时,会将组内第一个观测的score值重复赋值给组内所有观测。这是因为ifelse会自动循环长度不匹配的向量,但返回值处理时会取第一个元素填充。if_else:直接报错,原因是n()>1返回的是每组长度为1的逻辑值,而score是每组长度等于组内观测数的向量,两者尺寸不匹配——if_else要求条件、真返回值、假返回值的长度必须严格一致。case_when:符合预期,条件满足时保留每组每个观测的原始score值,它会自动将长度为1的条件向量循环匹配组内所有观测。
正确使用if_else的方法
不需要只能用case_when,只需将条件向量扩展为和组内观测数一致的长度即可。可以用rep(n()>1, n())把每组的单个逻辑值重复n次,让条件向量长度和score匹配:
cms_patient_care2 <- cms_patient_care %>% arrange(ccn, measure_abbr)%>% group_by(ccn, measure_abbr)%>% mutate( score2 = ifelse(n()>1, score, 0), score3 = if_else(rep(n()>1, n()), score, 0), # 扩展条件向量长度 score4 = case_when( n()>1 ~ score, TRUE ~ 0) )%>% ungroup()
此时score3会和score4得到完全一致的结果,因为rep(n()>1, n())生成了与组内每行对应的逻辑向量,满足if_else的严格长度要求。
内容的提问来源于stack exchange,提问作者axel
相关产品推荐
相关产品推荐

