R propose max et min, mais je ne vois pas de moyen très rapide de trouver une autre valeur dans l'ordre, mis à part le tri du vecteur entier, puis la sélection d'une valeur x à partir de ce vecteur.
Existe-t-il un moyen plus rapide d'obtenir la deuxième valeur la plus élevée, par exemple?
topn
fonction qui est plus rapide quesort
,order
etnth
. Regardez la documentation.Réponses:
Rfast a une fonction appelée nth_element qui fait exactement ce que vous demandez et est plus rapide que toutes les implémentations décrites ci-dessus
De plus, les méthodes décrites ci-dessus qui sont basées sur un tri partiel ne prennent pas en charge la recherche des k plus petites valeurs
Renvoie le 5e plus grand élément de x, tandis que
Renvoie le 5e plus petit élément de x
Benchmarks ci-dessous par rapport aux réponses les plus populaires.
Pour 10 mille numéros:
Pour 1 million de numéros:
la source
Rfast::nth
peut renvoyer plusieurs éléments (par exemple les 8ème et 9ème éléments les plus grands) ainsi que les indices de ces éléments.Utilisez l'
partial
argument desort()
. Pour la deuxième valeur la plus élevée:la source
sort(x, TRUE)[2]
celle décrite dans la réponse de @ Abrar, en dehors de ne pas satisfaire la contrainte de la question?Error in sort.int(x, na.last = na.last, decreasing = decreasing, ...) : index 4705 outside bounds
Une idée de quel pourrait être le problème? Quelques détails: My x est un vecteur numérique de longueur 4706 avec quelquesNA
s dans les données. J'ai essayé d'obtenir la deuxième valeur la plus élevée du vecteur en utilisant exactement le même code que @RobHyndman suggéré.decreasing
argument ne soit pas compatible avec le tri partiel, vous pouvez toujours-sort(-x, partial=n-1)[n-1]
; c'est logiquement la même chose et prend beaucoup moins de temps quesort(x, decreasing=TRUE)[n-1]
.Alternative légèrement plus lente, juste pour les enregistrements:
la source
max(x[-which.max(x)])
J'ai enveloppé la réponse de Rob dans une fonction un peu plus générale, qui peut être utilisée pour trouver le 2e, 3e, 4e (etc.) max:
la source
maxN(1:10, 1:3)
(j'aurais mis le N par défaut à 1)Voici un moyen simple de trouver les indices de N plus petites / plus grandes valeurs dans un vecteur (Exemple pour N = 3):
N Plus petit:
N Plus grand:
Ainsi, vous pouvez extraire les valeurs comme suit:
la source
Pour la nième valeur la plus élevée,
la source
J'ai trouvé que supprimer d'abord l'élément max, puis faire un autre max fonctionne à une vitesse comparable:
la source
Voici le moyen le plus simple que j'ai trouvé,
la source
Quand je cherchais récemment une fonction R renvoyant les index des N premiers nombres max / min dans un vecteur donné, j'ai été surpris qu'il n'y ait pas une telle fonction.
Et c'est quelque chose de très similaire.
La solution de force brute utilisant la fonction base :: order semble être la plus simple.
Mais ce n'est pas le plus rapide au cas où votre valeur N serait relativement petite par rapport à la longueur du vecteur x .
De l'autre côté, si le N est vraiment petit, vous pouvez utiliser la fonction base :: whichMax de manière itérative et à chaque itération, vous pouvez remplacer la valeur trouvée par -Inf
Je crois que vous voyez le problème - la nature de copie sur modification de R. Donc, cela fonctionnera mieux pour très très très petit N (1, 2, 3) mais il ralentira rapidement pour des valeurs de N plus grandes. Et vous itérez sur tous les éléments en vecteur x N fois.
Je pense que la meilleure solution dans clean R est d'utiliser partial base :: sort .
Ensuite, vous pouvez sélectionner le dernier ( N ème) élément du résultat des fonctions définies ci-dessus.
Remarque: les fonctions définies ci-dessus ne sont que des exemples - si vous souhaitez les utiliser, vous devez vérifier les entrées / sanity (par exemple N> longueur (x) ).
J'ai écrit un petit article sur quelque chose de très similaire (obtenir les index des N meilleures valeurs max / min d'un vecteur) sur http://palusga.cz/?p=18 - vous pouvez trouver ici quelques repères de fonctions similaires que j'ai définies ci-dessus.
la source
head(sort(x),..)
outail(sort(x),...)
devrait fonctionnerla source
cette fonction renverra une matrice avec les n premières valeurs et leurs indices. espérons que cela aide VDevi-Chou
la source
Ceci trouvera l'indice de la N'th plus petite ou plus grande valeur dans le vecteur numérique d'entrée x. Définissez bottom = TRUE dans les arguments si vous voulez le N'th du bas, ou bottom = FALSE si vous voulez le N'th du haut. N = 1 et bottom = TRUE est équivalent à which.min, N = 1 et bottom = FALSE est équivalent à which.max.
la source
dplyr a la fonction nth, où le premier argument est le vecteur et le second est l'emplacement souhaité. Cela vaut également pour les éléments répétés. Par exemple:
Trouver la deuxième valeur la plus élevée:
la source
x[[order(order_by)[[n]]]]
- il faut donc trier tout le vecteur. Ce ne sera donc pas aussi rapide que la réponse acceptée.sort
avec l'argument partial = (qui change tout)dplyr::nth()
?bench::mark(max(x[-which.max(x)]), x[[order(-x)[[2]]]] )
,nth()
semble presque 10 fois plus lent, oùlength(x)
est 3 millions.Vous pouvez identifier la valeur immédiatement supérieure avec
cummax()
. Si vous voulez par exemple l'emplacement de chaque nouvelle valeur supérieure, vous pouvez transmettre votre vecteur decummax()
valeurs à ladiff()
fonction pour identifier les emplacements où lacummax()
valeur a changé. disons que nous avons le vecteurMaintenant, si vous voulez trouver l'emplacement d'un changement,
cummax()
vous avez de nombreuses options que j'ai tendance à utilisersign(diff(cummax(v)))
. Vous devez ajuster le premier élément perdu à cause dediff()
. Le code complet du vecteurv
serait:la source
Vous pouvez utiliser le
sort
mot - clé comme ceci:Exemple:
donnera les 5 premiers nombres maximum.
la source