R oferuje max i min, ale nie widzę naprawdę szybkiego sposobu na znalezienie innej wartości w zamówieniu, poza sortowaniem całego wektora, a następnie wybraniem wartości x z tego wektora.
Czy jest na przykład szybszy sposób uzyskania drugiej najwyższej wartości?
topn
funkcję, która jest szybsza niżsort
,order
inth
. Spójrz na dokumentację.Odpowiedzi:
Użyj
partial
argumentusort()
. Dla drugiej największej wartości:źródło
sort(x, TRUE)[2]
opisanej w odpowiedzi @ Abrar, poza niespełnieniem ograniczenia zawartego w pytaniu?Error in sort.int(x, na.last = na.last, decreasing = decreasing, ...) : index 4705 outside bounds
Masz pojęcie, na czym może polegać problem? Kilka szczegółów: My x jest wektorem numerycznym o długości 4706 z kilkomaNA
s w danych. Próbowałem uzyskać drugą najwyższą wartość w wektorze, używając dokładnie tego samego kodu, co sugerował @RobHyndman.decreasing
argument nie jest zgodny z częściowym sortowaniem, zawsze możesz-sort(-x, partial=n-1)[n-1]
; jest to logicznie to samo i zajmuje znacznie mniej czasu niżsort(x, decreasing=TRUE)[n-1]
.Nieco wolniejsza alternatywa, tylko dla rekordów:
źródło
max(x[-which.max(x)])
Zawinąłem odpowiedź Roba w nieco bardziej ogólną funkcję, której można użyć do znalezienia drugiego, trzeciego, czwartego (itd.) Maksimum:
źródło
maxN(1:10, 1:3)
(domyślnieRfast ma funkcję o nazwie nth_element, która robi dokładnie to, o co prosisz i jest szybsza niż wszystkie implementacje omówione powyżej
Również metody omówione powyżej, które są oparte na sortowaniu częściowym, nie obsługują znajdowania k najmniejszych wartości
Zwróci piąty co do wielkości element x, a
Zwróci 5. najmniejszy element x
Poniższe testy porównawcze z najpopularniejszymi odpowiedziami.
Za 10 tysięcy numerów:
Za 1 milion numerów:
źródło
Rfast::nth
może zwrócić wiele elementów (np. 8. i 9. największy element), a także indeksy tych elementów.Oto prosty sposób na znalezienie indeksów N najmniejszych / największych wartości w wektorze (przykład dla N = 3):
N najmniejszy:
N Największy:
Możesz więc wyodrębnić wartości jako:
źródło
Dla n-tej najwyższej wartości,
źródło
Odkryłem, że najpierw usuwam element max, a następnie wykonuję kolejne przebiegi maksymalne z porównywalną prędkością:
źródło
Oto najprostszy sposób, jaki znalazłem,
źródło
Kiedy ostatnio szukałem funkcji R zwracającej indeksy najwyższych N max / min w danym wektorze, byłem zaskoczony, że nie ma takiej funkcji.
I to jest coś bardzo podobnego.
Rozwiązanie siłowe wykorzystujące funkcję base :: order wydaje się najłatwiejsze.
Ale nie jest to najszybsze, jeśli wartość N jest stosunkowo mała w porównaniu z długością wektora x .
Z drugiej strony, jeśli N jest naprawdę małe, możesz użyć iteracyjnie funkcji base :: whichMax, aw każdej iteracji możesz zastąpić znalezioną wartość -Inf
Wydaje mi się, że widzisz problem - naturę R. polegającą na kopiowaniu przy modyfikacji, więc będzie to działać lepiej dla bardzo, bardzo, bardzo małych N (1, 2, 3), ale szybko zwolni przy większych wartościach N. I iterujesz po wszystkich elementach w wektorze x N razy.
Myślę, że najlepszym rozwiązaniem w czystym R jest użycie częściowej bazy :: sort .
Następnie możesz wybrać ostatnią ( N- tą) pozycję z wyniku funkcji defiend powyżej.
Uwaga: funkcje zdefiniowane powyżej to tylko przykłady - jeśli chcesz z nich skorzystać, musisz sprawdzić dane wejściowe / sanity (np. N> length (x) ).
Napisałem mały artykuł o czymś bardzo podobnym (pobierz indeksy górnych wartości N max / min wektora) na http://palusga.cz/?p=18 - możesz znaleźć tutaj kilka testów podobnych funkcji, które zdefiniowałem powyżej.
źródło
head(sort(x),..)
lubtail(sort(x),...)
powinien działaćźródło
ta funkcja zwróci macierz z n górnymi wartościami i ich indeksami. mam nadzieję, że to pomaga VDevi-Chou
źródło
Pozwoli to znaleźć indeks N-tej najmniejszej lub największej wartości w wejściowym wektorze liczbowym x. Ustaw bottom = TRUE w argumentach, jeśli chcesz, aby N-ty od dołu, lub bottom = FALSE, jeśli chcesz, aby N-ty od góry. N = 1 i bottom = TRUE jest równoważne któremu. Min, N = 1 i bottom = FALSE jest równoważne któremu. Max.
źródło
dplyr ma funkcję nth, gdzie pierwszy argument to wektor, a drugi to żądane miejsce. Dotyczy to również powtarzających się elementów. Na przykład:
Znajdowanie drugiej największej wartości:
źródło
x[[order(order_by)[[n]]]]
- więc wymaga sortowania całego wektora. Więc nie będzie tak szybko, jak zaakceptowana odpowiedź.sort
z argumentem częściowym = (który zmienia wszystko)dplyr::nth()
?bench::mark(max(x[-which.max(x)]), x[[order(-x)[[2]]]] )
,nth()
wydaje się prawie 10 razy wolniejszy, gdzielength(x)
wynosi 3 miliony.Możesz zidentyfikować następną wyższą wartość za pomocą
cummax()
. Jeśli chcesz na przykład lokalizację każdej nowej wyższej wartości, możesz przekazać swój wektorcummax()
wartości dodiff()
funkcji, aby zidentyfikować lokalizacje, w którychcummax()
wartość uległa zmianie. powiedzmy, że mamy wektorTeraz, jeśli chcesz znaleźć lokalizację zmiany
cummax()
, masz wiele opcji, z których zwykle korzystamsign(diff(cummax(v)))
. Musisz dostosować się do utraconego pierwszego elementu z powodudiff()
. Pełny kod dla wektorav
wyglądałby tak:źródło
Możesz użyć tego
sort
słowa kluczowego w następujący sposób:Przykład:
poda pierwsze 5 maksymalnych liczb.
źródło