在向量中查找最近的非缺失值

时间:2013-07-11 21:37:12

标签: r vector missing-data

我正在尝试使用非缺失值返回向量中的最新行。例如,给定

x <- c(1,2,NA,NA,3,NA,4)

然后函数(x)将输出如下列表:

c(1,2,2,2,3,3,4)

非常简单的问题,但在多列上使用循环或暴力运行它需要永远。

2 个答案:

答案 0 :(得分:4)

您可以zoo::na.locf使用

require(zoo)
x <- c(1, 2, NA, NA, 3, NA, 4)
na.locf(x)
## [1] 1 2 2 2 3 3 4

答案 1 :(得分:2)

您可以使用Reduce功能执行此操作:

> x <- c(1,2,NA,NA,3,NA,4)
> locf <- function(x,y) if(is.na(y)) x else y
> Reduce( locf, x, accumulate=TRUE )
[1] 1 2 2 2 3 3 4

这样您就不需要加载额外的包(如果需要,可以根据不同类型的对象进行自定义)。

对于我的计算机上的示例向量,Reduce选项比zoo::na.locf更快:

> library(zoo)
> library(microbenchmark)
> 
> microbenchmark( 
+ Reduce( locf, x, accumulate=TRUE ),
+ na.locf(x)
+ )
Unit: microseconds
                               expr     min       lq  median       uq     max
 Reduce(locf, x, accumulate = TRUE)  22.169  24.0160  27.506  29.3530 112.073
                         na.locf(x) 149.841 151.8945 154.357 169.5465 377.271
 neval
   100
   100

虽然可能还有其他情况na.locf会更快。实际上我对差异的数量感到惊讶。


对较大数据进行基准测试可显示na.locf来自zoo包与使用Reduce之间的差异:

x <- sample(c(1:5, NA), 1e6, TRUE)
require(zoo)
require(microbenchmark)
locf <- function(x,y) if(is.na(y)) x else y

microbenchmark(Reduce( locf, x, accumulate=TRUE ), na.locf(x), times=10)
Unit: milliseconds
                              expr       min        lq    median       uq      max neval
Reduce(locf, x, accumulate = TRUE) 5480.4796 5958.0905 6605.3547 7458.404 7915.046    10
                        na.locf(x)  661.2886  911.1734  950.2542 1026.348 1095.642    10