正如我们从this answer学到的,当使用anyNA()而不是any(is.na())来检测一个向量是否至少有一个NA元素时,性能会有很大的提高.这是有意义的,因为anyNA()的算法在它找到的第一个NA值之后停止,而any(is.na())必须首先用is.na()遍历整个向量.

相比之下,我想知道一个向量是否至少有1,non-NA个值.这意味着我正在寻找一个在第一次遇到非NA值后停止的实现.是的,我可以使用any(!is.na()),但是我面临着让is.na()首先遍历整个向量的问题.

是否存在与anyNA()相反的performant,即"anyNonNA()"?

推荐答案

我不知道有哪个本机函数会在遇到非NA值时停止,但我们可以使用RCPP编写一个简单的函数:

Rcpp::cppFunction("bool any_NonNA(NumericVector v) {
  for(size_t i = 0; i < v.length(); i++) {
   if(!(Rcpp::traits::is_na<REALSXP>(v[i]))) return true;
  }
  return false;
}")

这将创建一个名为any_NonNA的R函数,它执行我们所需的操作.让我们在一个有any_NonNA,000 nA值的大向量上测试它:

test <- rep(NA, 1e5)

any_NonNA(test)
#> [1] FALSE

any(!is.na(test))
#> [1] FALSE

现在,让我们将第一个元素设为非NA:

test[1] <- 1

any_NonNA(test)
#> [1] TRUE

any(!is.na(test))
#> [1] TRUE

所以它给出了正确的结果,但它更快吗?

当然,在本例中,因为它应该在第一个元素之后停止,所以它应该快得多.如果我们逐一比较,情况确实是这样:

microbenchmark::microbenchmark(
  baseR = any(!is.na(test)),
  Rcpp  = any_NonNA(test)
)
#> Unit: microseconds
#> expr   min    lq    mean median    uq     max neval cld
#> baseR 275.1 525.0 670.948 533.05 568.7 13029.9   100   b
#> Rcpp   1.6   2.1   4.319   3.30   5.1    33.7   100  a 

正如预期的那样,这要快几个数量级.如果我们的第一个非NA值位于向量的中间,情况会怎样呢?

test[1] <- NA
test[50000] <- 1

microbenchmark::microbenchmark(
  baseR = any(!is.na(test)),
  Rcpp  = any_NonNA(test)
)
#> Unit: microseconds
#> expr   min     lq    mean median     uq     max neval cld
#> baseR 332.1 579.35 810.948 597.95 624.40 12010.4   100   b
#> Rcpp 299.4 300.70 311.516 305.10 309.25   370.1   100  a 

速度更快,但不会太快.

如果我们把非NA值放在最后,我们应该看不到太大的区别:

test[50000] <- NA
test[100000] <- 1

microbenchmark::microbenchmark(
  baseR = any(!is.na(test)),
  Rcpp  = any_NonNA(test)
)
#> Unit: microseconds
#> expr   min     lq    mean median    uq     max neval cld
#> baseR 395.6 631.65 827.173  642.6 663.8 11357.0   100   a
#> Rcpp 596.3 602.25 608.011  605.8 612.6   632.6   100   a

因此,这看起来确实比基本R解更快(至少对大矢量来说是这样).

R相关问答推荐

如何在四进制仪表板值框中显示值(使用shiny 的服务器计算)

R中具有gggplot 2的Likert图,具有不同的排名水平和显示百分比

在垂直轴中包含多个ggplot2图中的平均值

从BRM预测价值

R中插入符号训练函数的中心因子和尺度因子预测

一小时满足条件的日期的 Select

如何写商,水平线,在一个单元格的表在R

plotly hover文本/工具提示在shiny 中不起作用

在不丢失空值的情况下取消列出嵌套列表

在R中创建连续的期间

我如何使用循环来编写冗余的Rmarkdown脚本?

在ggplot2上从多个数据框创建复杂的自定义图形

R中时间间隔的大向量与参考时间间隔的相交

按组和连续id计算日期差

变异以按组从其他列创建具有最大和最小值的新列

按组使用dummy r获取高于标准的行的平均值

如何在R中创建这些列?

创建由三个单独的shapefile组成的单个 map

如何从矩阵绘制环弦图

如何在基数R中根据矩阵散点图中的因子给数据上色?