为何RcppRoll的roll_median(na.rm=TRUE)遇10个NA返回值,11个NA返回NA?
RcppRoll包
roll_median(..., na.rm=TRUE)的NA处理行为疑问 在使用RcppRoll包的roll_medianr函数(指定na.rm=TRUE)时,发现一个令人困惑的行为:当窗口内存在11个NA值时,函数返回NA;但窗口内存在10个NA值时,却能返回有效的中位数结果。
注:dplyr窗口函数文档中提到可使用RcppRoll计算滚动聚合,因此RcppRoll与dplyr的组合使用较为普遍,本文聚焦于解释上述特定行为的逻辑。
具体示例
1. 0个NA值的基础计算
suppressPackageStartupMessages(library(dplyr)) library(RcppRoll) mtcars %>% transmute(myroll = roll_medianr(mpg, n = nrow(mtcars), na.rm = TRUE)) %>% tail(1) # myroll # Volvo 142E 19.2
2. 10个NA值时返回有效中位数
mtcars %>% mutate(mpg = ifelse(row_number() <= 10, NA, mpg)) %>% transmute(myroll = roll_medianr(mpg, n = nrow(mtcars), na.rm = TRUE)) %>% tail(1) # myroll # Volvo 142E 15.1
3. 11个NA值时返回NA
mtcars %>% mutate(mpg = ifelse(row_number() <= 11, NA, mpg)) %>% transmute(myroll = roll_medianr(mpg, n = nrow(mtcars), na.rm = TRUE)) %>% tail(1) # myroll # Volvo 142E NA
核心疑问
暂不关注具体返回的数值大小,仅聚焦返回结果是NA还是有效值:为何上述场景中,窗口内有10个NA时能返回有效值,有11个NA时却返回NA?
目前在RcppRoll的官方文档及网络搜索中未找到相关解释,主要希望理解该行为的底层逻辑。
其他包实现对比(以zoo为例)
已知可以通过zoo包的rollapplyr函数实现滚动中位数,且不会出现上述NA阈值问题:
10个NA值的情况
suppressPackageStartupMessages(library(zoo)) mtcars %>% mutate(mpg = ifelse(row_number() <= 10, NA, mpg)) %>% transmute(myroll = rollapplyr(mpg, width = nrow(mtcars), FUN = median, na.rm = TRUE, fill = NA)) %>% tail(1) # myroll # Volvo 142E 17.55
11个NA值的情况
mtcars %>% mutate(mpg = ifelse(row_number() <= 11, NA, mpg)) %>% transmute(myroll = rollapplyr(mpg, width = nrow(mtcars), FUN = median, na.rm = TRUE, fill = NA)) %>% tail(1) # myroll # Volvo 142E 17.3
内容的提问来源于stack exchange,提问作者jmuhlenkamp
相关产品推荐
相关产品推荐

