使用tidyverse(dplyr)计算含NA的条件求和时的缺失值处理问题
解决dplyr求和中NA值导致结果不符的问题
我来帮你分析下这个问题哈~
你遇到的核心问题是NA值在加法运算中会导致整个表达式结果变为NA,而后续的sum(na.rm=T)会直接跳过这些NA值,相当于丢失了对应行的贡献。具体到你的数据:
- 第四行的
effectif2是NA,所以effectif+effectif2的结果是NA - 虽然
in_flores>=1的条件成立,但if_else返回了NA,sum(na.rm=T)会忽略这个NA,导致第四行的30没有被计入总和,最终CP2组的effeff2只算了第三行的34(20+14),和你期望的64不符。
要解决这个问题,我们需要把effectif2中的NA替换为0,这样即使遇到NA,加法运算也能正常得到有效值。这里推荐用dplyr::coalesce()函数,它可以自动把NA替换成指定的默认值。
方案一:在加法运算中直接处理NA
library(dplyr) toto <- data.frame( classe = c("CP","CP2","CP2","CP2"), in_flores = c(1,0,1,1), effectif = c(10,50,20,30), effectif2 = c(10,50,14,NA) ) toto %>% group_by(classe) %>% summarise( eff = if_else(in_flores>=1, effectif, 0) %>% sum(na.rm = T), effeff2 = if_else(in_flores>=1, effectif + coalesce(effectif2, 0), 0) %>% sum(na.rm = T) )
方案二:提前预处理NA值(可读性更好)
如果你觉得在加法里嵌套函数不够直观,可以先把effectif2的NA替换为0,再进行后续计算:
toto %>% mutate(effectif2 = coalesce(effectif2, 0)) %>% group_by(classe) %>% summarise( eff = sum(if_else(in_flores>=1, effectif, 0), na.rm = T), effeff2 = sum(if_else(in_flores>=1, effectif + effectif2, 0), na.rm = T) )
运行任意一种方案后,CP2组的effeff2都会得到64,符合你的预期。
内容的提问来源于stack exchange,提问作者Damien Dotta
相关产品推荐
相关产品推荐

