我正在尝试以非缺失值返回向量中的最新行。例如,给定
x <- c(1,2,NA,NA,3,NA,4)
然后 function(x) 将输出一个列表,如:
c(1,2,2,2,3,3,4)
非常简单的问题,但是在多列上使用循环或蛮力运行它需要很长时间。
我正在尝试以非缺失值返回向量中的最新行。例如,给定
x <- c(1,2,NA,NA,3,NA,4)
然后 function(x) 将输出一个列表,如:
c(1,2,2,2,3,3,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
您可以使用以下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
from zoo
package 和 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