当我最近在寻找一个返回给定向量中前 N 个最大/最小数字的索引的 R 函数时,我很惊讶没有这样的函数。
这是非常相似的。
使用 base::order 函数的蛮力解决方案似乎是最简单的。
topMaxUsingFullSort <- function(x, N) {
sort(x, decreasing = TRUE)[1:min(N, length(x))]
}
但如果您的 N 值与向量 x 的长度相比相对较小,它并不是最快的。
另一方面,如果 N 真的很小,您可以迭代地使用 base::whichMax 函数,并且在每次迭代中,您可以将找到的值替换为 -Inf
# the input vector 'x' must not contain -Inf value
topMaxUsingWhichMax <- function(x, N) {
vals <- c()
for(i in 1:min(N, length(x))) {
idx <- which.max(x)
vals <- c(vals, x[idx]) # copy-on-modify (this is not an issue because idxs is relative small vector)
x[idx] <- -Inf # copy-on-modify (this is the issue because data vector could be huge)
}
vals
}
我相信您看到了问题 - R 的修改时复制性质。因此,对于非常非常非常小的 N (1,2,3),这将表现得更好,但对于较大的 N 值,它会迅速减慢。你正在迭代向量中的所有元素 x N 次。
我认为干净 R 中最好的解决方案是使用部分 base::sort。
topMaxUsingPartialSort <- function(x, N) {
N <- min(N, length(x))
x[x >= -sort(-x, partial=N)[N]][1:N]
}
然后你可以从上面defiend函数的结果中选择最后一个(Nth)项。
注意:上面定义的函数只是示例 - 如果您想使用它们,您必须检查/健全输入(例如。N > length(x))。
我在http://palusga.cz/?p=18 写了一篇关于非常相似的小文章(获取向量的前 N 个最大值/最小值的索引) - 你可以在这里找到我上面定义的类似函数的一些基准。