Когда я недавно искал функцию R , возвращающую индексы верхних N max / min чисел в данном векторе, я был удивлен, что такой функции нет.
И это нечто очень похожее.
Решение о грубой силе, использующее функцию 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]
}
Затем вы можете выбрать последний ( N th) элемент из результата функций, описанных выше.
Примечание: функции, определенные выше, являются просто примерами - если вы хотите их использовать, вы должны проверить / рассудить входные данные (например, N> length (x) ).
Я написал небольшую статью о чем-то очень похожем (получите индексы максимальных значений N max / min вектора) в http://palusga.cz/?p=18 - здесь вы можете найти некоторые тесты аналогичных функций, которые я определил выше.