R语言中使用purrr::reduce结合lag实现累加时忽略缺失值的实现问题
R语言中使用purrr::reduce结合lag实现累加时忽略缺失值的实现问题
嗨,我看你遇到了用reduce结合lag做累加时被NA干扰的问题,咱们来一步步解决它~
首先得说清楚你当前代码的问题:你用了基础的+运算符来做reduce的累积运算,但R里的+只要碰到NA就会直接返回NA,所以只要当前值或者前一个值是NA,结果就变成NA了,这就是为什么第三行和第四行的addition都是NA,不符合你的预期。
接下来给你两种可行的解决方案,按需选择就行:
方案一:用rowSums直接实现(更简洁)
其实你的需求本质是计算当前值b和它的前一个值(lag(b))的和,并且忽略NA。那直接把这两列合并后逐行求和,加上na.rm = TRUE参数就能搞定,代码非常简洁:
library(dplyr) a <- data.frame(b = c(1, 2, NA, 3, 4, 5)) a %>% mutate(addition = rowSums(cbind(b, lag(b)), na.rm = TRUE))
运行后就能得到你想要的结果:
| b | addition |
|---|---|
| 1 | 1 |
| 2 | 3 |
| NA | 2 |
| 3 | 3 |
| 4 | 7 |
| 5 | 9 |
如果之后你需要扩展到更多的lag值(比如同时加当前值、前1、前2的值),只要在cbind里多加对应的lag(b, 2)就行,非常灵活。
方案二:自定义安全加法函数适配reduce
如果你坚持要用reduce+map的组合,那只需要把默认的+运算符换成一个能忽略NA的加法函数就行。先定义一个“安全加法”函数,它会用sum并开启na.rm参数来自动忽略NA:
library(dplyr) library(purrr) # 自定义忽略NA的加法函数 safe_add <- function(x, y) { sum(x, y, na.rm = TRUE) } a <- data.frame(b = c(1, 2, NA, 3, 4, 5)) a %>% mutate(addition = reduce(map(0:1, ~lag(b, .x)), safe_add))
这样运行后也能得到你期望的结果,原理就是每次reduce累积的时候,都会自动跳过NA值进行求和。
备注:内容来源于stack exchange,提问作者user2360397
相关产品推荐
相关产品推荐

