Нет связей which()
, вероятно, ваш друг здесь. Объедините выходные данные решения sort()
с which()
, чтобы найти индекс, который соответствует выходным данным шага sort()
.
> set.seed(1)
> x <- sample(1000, 250)
> sort(x,partial=n-1)[n-1]
[1] 992
> which(x == sort(x,partial=n-1)[n-1])
[1] 145
Обработка связей Приведенное выше решение не работает должным образом (и не предназначалось для этого), если есть связи, и связи - это значения, которые являются i-м наибольшим или большим значениями. Нам нужно взять уникальные значения вектора перед сортировкой этих значений, и тогда вышеприведенное решение работает:
> set.seed(1)
> x <- sample(1000, 1000, replace = TRUE)
> length(unique(x))
[1] 639
> n <- length(x)
> i <- which(x == sort(x,partial=n-1)[n-1])
> sum(x > x[i])
[1] 0
> x.uni <- unique(x)
> n.uni <- length(x.uni)
> i <- which(x == sort(x.uni, partial = n.uni-1)[n.uni-1])
> sum(x > x[i])
[1] 2
> tail(sort(x))
[1] 994 996 997 997 1000 1000
order()
также очень полезен здесь:
> head(ord <- order(x, decreasing = TRUE))
[1] 220 145 209 202 211 163
Таким образом, решение здесь ord[2]
для индекса 2-го старшего / самого большого элемента x
.
Некоторые тайминги:
> set.seed(1)
> X <- sample(1e7, 1e7)
> system.time({n <- length(X); which(X == sort(X, partial = n-1)[n-1])})
user system elapsed
0.319 0.058 0.378
> system.time({ord <- order(X, decreasing = TRUE); ord[2]})
user system elapsed
14.578 0.084 14.708
> system.time({order(X, decreasing = TRUE)[2]})
user system elapsed
14.647 0.084 14.779
Но поскольку ссылка на публикацию доходила до времени, показанного выше, order()
намного медленнее, но оба дают одинаковые результаты:
> all.equal(which(X == sort(X, partial = n-1)[n-1]),
+ order(X, decreasing = TRUE)[2])
[1] TRUE
А для версии обработки связей:
foo <- function(x, i) {
X <- unique(x)
N <- length(X)
i <- i-1
which(x == sort(X, partial = N-i)[N-i])
}
> system.time(foo(X, 2))
user system elapsed
1.249 0.176 1.454
Таким образом, дополнительные шаги немного замедляют это решение, но оно все еще очень конкурентоспособно с order()
.