Najszybszy sposób znalezienia drugiej (trzeciej...) najwyższej / najniższej wartości w wektorze lub kolumnie
R oferuje max i min, ale nie widzę naprawdę szybkiego sposobu na znalezienie innej wartości w kolejności oprócz sortowania całego wektora I niż wybranie wartości x z tego wektora.
Czy istnieje szybszy sposób na uzyskanie drugiej najwyższej wartości (np.)?
Thanks
13 answers
Użyj argumentu partial
z sort()
. Dla drugiej najwyższej wartości:
n <- length(x)
sort(x,partial=n-1)[n-1]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-16 10:41:24
Nieco wolniejsza alternatywa, tylko dla płyt:
x <- c(12.45,34,4,0,-234,45.6,4)
max( x[x!=max(x)] )
min( x[x!=min(x)] )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-16 11:49:31
Owinąłem odpowiedź Roba w nieco bardziej ogólną funkcję, która może być użyta do znalezienia 2., 3., 4. (itd."max": {]}
maxN <- function(x, N=2){
len <- length(x)
if(N>len){
warning('N greater than length(x). Setting N=length(x)')
N <- length(x)
}
sort(x,partial=len-N+1)[len-N+1]
}
maxN(1:10)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-08 19:47:39
Oto prosty sposób na znalezienie indeksów N najmniejszych / największych wartości w wektorze(przykład dla N = 3):
N <- 3
N Najmniejszy:
ndx <- order(x)[1:N]
N:
ndx <- order(x, decreasing = T)[1:N]
Więc możesz wyodrębnić wartości jako:
x[ndx]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-26 15:38:28
Dla n-tej najwyższej wartości,
sort(x, TRUE)[n]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-15 08:15:02
Stwierdziłem, że najpierw usuwam element max, a potem wykonuję kolejny max działa z porównywalną prędkością:
system.time({a=runif(1000000);m=max(a);i=which.max(a);b=a[-i];max(b)})
user system elapsed
0.092 0.000 0.659
system.time({a=runif(1000000);n=length(a);sort(a,partial=n-1)[n-1]})
user system elapsed
0.096 0.000 0.653
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 19:03:04
Kiedy ostatnio Szukałem R funkcji zwracającej indeksy top N max/min liczb w danym wektorze, byłem zaskoczony, że nie ma takiej funkcji.
I to jest coś bardzo podobnego.Rozwiązanie brute force przy użyciubase::order wydaje się być najprostszym rozwiązaniem.
topMaxUsingFullSort <- function(x, N) {
sort(x, decreasing = TRUE)[1:min(N, length(x))]
}
Ale nie jest to najszybszy w przypadku, gdy wartość N jest stosunkowo mała w porównaniu do długości wektora x .
Po drugiej stronie, jeśli N jest naprawdę mały, możesz użyć base::whichmax funkcji iteracyjnie i w każdej iteracji możesz zastąpić znalezioną wartość przez -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
}
Wierzę, że widzisz problem-kopiowanie na modyfikowanie natury R. więc będzie to działać lepiej dla bardzo bardzo bardzo małych N (1,2,3), ale to będzie szybko spowolnić dla większych wartości N. I powtarzasz wszystkie elementy w wektorze x N razy.
Myślę, że najlepszym rozwiązaniem w czystym R jest aby użyć częściowej base:: sort .
topMaxUsingPartialSort <- function(x, N) {
N <- min(N, length(x))
x[x >= -sort(-x, partial=N)[N]][1:N]
}
Następnie możesz wybrać ostatnią (Nth) pozycję z wyniku funkcji.
Uwaga: funkcje zdefiniowane powyżej są tylko przykładami - jeśli chcesz z nich korzystać, musisz sprawdzić / sanity inputs (np. N > długość(x)).
Napisałem mały artykuł o czymś bardzo podobnym (uzyskać indeksy najwyższych n max/min wartości wektora) na http://palusga.cz/?p=18 - znajdziesz tutaj kilka benchmarków podobnych funkcje, które zdefiniowałem powyżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-06 23:49:03
head(sort(x),..)
LUB tail(sort(x),...)
powinno działać
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 16:57:34
topn = function(vector, n){
maxs=c()
ind=c()
for (i in 1:n){
biggest=match(max(vector), vector)
ind[i]=biggest
maxs[i]=max(vector)
vector=vector[-biggest]
}
mat=cbind(maxs, ind)
return(mat)
}
Ta funkcja zwróci macierz z najwyższymi wartościami n i ich indeksami. mam nadzieję, że to pomoże VDevi-Chou
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-06 13:41:46
To znajdzie indeks N-tej najmniejszej lub największej wartości w wejściowym wektorze liczbowym x. Ustaw bottom = TRUE w argumentach, jeśli chcesz n - tą od dołu, lub bottom = FALSE, jeśli chcesz N-tą od góry. N=1 i bottom = TRUE jest równoważne which.min, N=1 i bottom=FALSE jest równoważne which.max.
FindIndicesBottomTopN <- function(x=c(4,-2,5,-77,99),N=1,bottom=FALSE)
{
k1 <- rank(x)
if(bottom==TRUE){
Nindex <- which(k1==N)
Nindex <- Nindex[1]
}
if(bottom==FALSE){
Nindex <- which(k1==(length(x)+1-N))
Nindex <- Nindex[1]
}
return(Nindex)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-31 14:04:40
Możesz zidentyfikować następną wyższą wartość za pomocą cummax()
. Jeśli chcesz określić położenie każdej nowej wyższej wartości, na przykład możesz przekazać swój wektor wartości {[2] } do funkcji diff()
, aby zidentyfikować miejsca, w których zmieniła się wartość cummax()
. powiedzmy, że mamy wektor
v <- c(4,6,3,2,-5,6,8,12,16)
cummax(v) will give us the vector
4 6 6 6 6 6 8 12 16
Teraz, jeśli chcesz znaleźć lokalizację zmiany w cummax()
masz wiele opcji, których zwykle używam sign(diff(cummax(v)))
. Musisz dopasować utracony pierwszy element z powodu diff()
. Kompletny kod dla wektora v
będzie be:
which(sign(diff(cummax(v)))==1)+1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-18 16:34:03
Możesz użyć słowa kluczowego sort
w następujący sposób:
sort(unique(c))[1:N]
Przykład:
c <- c(4,2,44,2,1,45,34,2,4,22,244)
sort(unique(c), decreasing = TRUE)[1:5]
Poda pierwsze 5 liczb max.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 12:15:33
Dplyr ma funkcję nth, gdzie pierwszy argument to wektor, a drugi to miejsce, które chcesz. Dotyczy to również powtarzających się elementów. Na przykład:
x = c(1,2, 8, 16, 17, 20, 1, 20)
Znalezienie drugiej co do wielkości wartości:
nth(unique(x),length(unique(x))-1)
[1] 17
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 14:51:19