检测向量NA
在R中是否至少有1的最快方法是什么?我一直在用:
sum( is.na( data ) ) > 0
Run Code Online (Sandbox Code Playgroud)
但这需要检查每个元素,强制和和函数.
Sac*_*amp 68
我在想:
any(is.na(data))
Run Code Online (Sandbox Code Playgroud)
应该稍快一些.
Bro*_*ieG 59
从R 3.1.0开始anyNA()
就是这样做的.在原子矢量上,这将在第一个NA之后停止,而不是通过整个矢量,就像那样any(is.na())
.另外,这避免了创建中间逻辑向量is.na
,并立即将其丢弃.借用乔兰的例子:
x <- y <- runif(1e7)
x[1e4] <- NA
y[1e7] <- NA
microbenchmark::microbenchmark(any(is.na(x)), anyNA(x), any(is.na(y)), anyNA(y), times=10)
# Unit: microseconds
# expr min lq mean median uq
# any(is.na(x)) 13444.674 13509.454 21191.9025 13639.3065 13917.592
# anyNA(x) 6.840 13.187 13.5283 14.1705 14.774
# any(is.na(y)) 165030.942 168258.159 178954.6499 169966.1440 197591.168
# anyNA(y) 7193.784 7285.107 7694.1785 7497.9265 7865.064
Run Code Online (Sandbox Code Playgroud)
注意即使我们修改向量的最后一个值,它也会快得多; 这部分是因为避免了中间逻辑矢量.
Dir*_*tel 16
我们在一些Rcpp演示文稿中提到了这一点,并且实际上有一些基准测试显示嵌入式C++与Rcpp在R解决方案上的相当大的收益,因为
向量化的R解决方案仍然计算向量表达式的每个单独元素
如果你的目标只是满足any()
,那么你可以在第一场比赛后中止 - 这就是我们的Rcpp糖(实质上:一些C++模板魔术使C++表达式看起来更像R表达式,请参阅此插图以获得更多)解决方案.
因此,通过编译专用解决方案,我们确实可以获得快速解决方案.我应该补充一点,虽然我没有将此与此SO问题中提供的解决方案进行比较,但我对性能有了相当的信心.
编辑并且Rcpp包中包含目录中的示例sugarPerformance
.对于'R-computes-full-vector-expression'而言any()
,它已经增加了几千个"糖罐中止" ,但是我应该补充一点,这个案例不涉及is.na()
一个简单的布尔表达式.
可以写一个for循环停止在NA,但system.time然后取决于NA的位置...(如果没有,它需要looooong)
set.seed(1234)
x <- sample(c(1:5, NA), 100000000, replace = TRUE)
nacount <- function(x){
for(i in 1:length(x)){
if(is.na(x[i])) {
print(TRUE)
break}
}}
system.time(
nacount(x)
)
[1] TRUE
User System verstrichen
0.14 0.04 0.18
system.time(
any(is.na(x))
)
User System verstrichen
0.28 0.08 0.37
system.time(
sum(is.na(x)) > 0
)
User System verstrichen
0.45 0.07 0.53
Run Code Online (Sandbox Code Playgroud)
以下是我(慢)机器的一些实际时间,用于讨论到目前为止所讨论的各种方法:
x <- runif(1e7)
x[1e4] <- NA
system.time(sum(is.na(x)) > 0)
> system.time(sum(is.na(x)) > 0)
user system elapsed
0.065 0.001 0.065
system.time(any(is.na(x)))
> system.time(any(is.na(x)))
user system elapsed
0.035 0.000 0.034
system.time(match(NA,x))
> system.time(match(NA,x))
user system elapsed
1.824 0.112 1.918
system.time(NA %in% x)
> system.time(NA %in% x)
user system elapsed
1.828 0.115 1.925
system.time(which(is.na(x) == TRUE))
> system.time(which(is.na(x) == TRUE))
user system elapsed
0.099 0.029 0.127
Run Code Online (Sandbox Code Playgroud)
这并不奇怪,match
并且%in%
类似,因为%in%
使用match
.
归档时间: |
|
查看次数: |
69771 次 |
最近记录: |