gpt4 book ai didi

r - 在 R 中使用 which() 函数时进行矢量化

转载 作者:行者123 更新时间:2023-12-01 16:56:08 25 4
gpt4 key购买 nike

我有 3 个向量,我想分别对每个向量应用“which()”函数。我试图找到小于某个给定数字的值的最大索引。如何使用矢量化操作此任务?

我的 3 个向量(可能有不同的长度)

vec1 <- c(1,2,3,4,5)
vec2 <- c(11,12,13)
vec3 <- c(1,2,3,4,5,6,7,8)

我如何对其进行矢量化?

max(which(vec1<3))
max(which(vec2<12.3))
max(which(vec3<5.7))

预期的结果是:

2
2
5

最佳答案

获得加速的一种方法是使用 Rcpp 搜索小于您的截止值的元素,从向量的右侧开始向左移动。您可以在找到符合条件的元素后立即返回,这意味着如果您的目标靠近向量的右侧,您可能会避免查看向量的大部分元素(同时,哪个查看所有向量元素,max 查看 which 返回的所有值)。对于目标元素接近末尾的长向量,加速比最大。

library(Rcpp)
rightmost.small <- cppFunction(
'double rightmostSmall(NumericVector x, const double cutoff) {
for (int i=x.size()-1; i >= 0; --i) {
if (x[i] < cutoff) return i+1; // 1-index
}
return 0; // None found
}')
rightmost.small(vec1, 3)
# [1] 2
rightmost.small(vec2, 12.3)
# [1] 2
rightmost.small(vec3, 5.7)
# [1] 5

让我们看一下向量的性能,我们希望它能给我们带来很大的加速:

set.seed(144)
vec.large <- rnorm(1000000)
all.equal(max(which(vec.large < -1)), rightmost.small(vec.large, -1))
# [1] TRUE
library(microbenchmark)
microbenchmark(max(which(vec.large < -1)), rightmost.small(vec.large, -1))
# Unit: microseconds
# expr min lq mean median uq max neval
# max(which(vec.large < -1)) 4912.016 8097.290 12816.36406 9189.0685 9883.9775 60405.585 100
# rightmost.small(vec.large, -1) 1.643 2.476 8.54274 8.8915 12.8375 58.152 100

对于这个长度为 100 万的向量,使用 Rcpp 代码我们可以看到大约 1000 倍的加速。

这种加速应该直接适用于列表中存储了许多向量的情况;您可以使用@JoshO'Brien 的mapply 代码并在从max(which(...)) 切换到Rcpp 时观察到加速代码:

f <- function(v,m) max(which(v < m))
l <- list(vec.large)[rep(1, 100)]
m <- rep(-1, 100)
microbenchmark(mapply(f, l, m), mapply(rightmost.small, l, m))
Unit: microseconds
expr min lq mean median uq max neval
mapply(f, l, m) 865287.828 907893.8505 931448.1555 918637.343 935632.0505 1133909.950 100
mapply(rightmost.small, l, m) 253.573 281.6855 344.5437 303.094 335.1675 712.897 100

通过使用此处的 Rcpp 代码,我们看到了 3000 倍的加速。

关于r - 在 R 中使用 which() 函数时进行矢量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28330449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com