Rcpp::cppFunction("
int which_non_na(LogicalVector x) {
R_xlen_t n = x.size();
for (R_xlen_t i = 0; i < n; ++i) {
if (!LogicalVector::is_na(x[i])) {
return i + 1; // +1 for 1-indexing in R
}
}
return NA_INTEGER; // if no non-NA values are found
}
")
which_non_na(x) # 4
Rcpp
即使第一个非值不是特别靠近开始,for 循环也应该很快。NA
基本思想是,找到第一个值后,您不需要继续迭代。基准
以下是一些长度为 的向量的基准测试
1e3
。1e8
对于长度为 1,000 的向量,这比 R 方法快约 9 倍。对于长度为 100,000,000 的向量,它平均快一百万倍以上。我也将其他答案添加到基准测试中。which.min()
比 快min(which())
,但对于这里最大的向量,这仍然比 快约 200,000 倍。输出:
您可以使用
which.min
andwhich.max
(不用is.na()
),因为如手册中所述:你会看到
评论
从基准测试来看,
is.na
从速度角度来看,它似乎是一个昂贵的运算符,尤其是当数组大小扩大时参加聚会已经很晚了,但没有看到任何人提到 Position() ,它可以完成您要寻找的操作,并在找到匹配项后立即停止扫描:
min
比使用和基础 R稍快一点即使在糟糕的 CPU 上,也能在不到一秒的时间内从 100,000,000 个值中找到第一个非 NA 值。
在 Intel Mac 上,OS 13.5.2
编辑:使用纯逻辑输入重新测试
不知道如果 C++ 在数字输入上运行但没有声明“逻辑”会如何。