1

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

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

然后 function(x) 将输出一个列表,如:

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

非常简单的问题,但是在多列上使用循环或蛮力运行它需要很长时间。

4

2 回答 2

5

你可以使用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
于 2013-07-11T21:43:39.260 回答
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.locffrom zoopackage 和 using之间的区别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
于 2013-07-12T17:21:52.927 回答