J'ai un bloc de données (mes_données) et je souhaite calculer la somme des 3 valeurs les plus élevées uniquement, même s'il peut y avoir des liens. Je suis assez nouveau dans R et j'ai utilisé dplyr
.
# A tibble: 3 x 2 city top_nr <chr> <dbl> 1 Lund 86 2 Stockholm 90 3 Uppsala 160
Voici le code que j'ai essayé:
# A tibble: 3 x 2 city top_nr <chr> <dbl> 1 Lund 86 2 Stockholm 75 3 Uppsala 130
Le résultat attendu (voulu) est:
# For each city, count the top 3 of variable number my_data %>% group_by(city) %>% top_n(3, number) %>% summarise(top_nr = sum(number))
mais la sortie réelle de R est:
A tibble: 15 x 3 city month number <chr> <chr> <dbl> 1 Lund jan 12 2 Lund feb 12 3 Lund mar 18 4 Lund apr 28 5 Lund may 28 6 Stockholm jan 15 7 Stockholm feb 15 8 Stockholm mar 30 9 Stockholm apr 30 10 Stockholm may 10 11 Uppsala jan 22 12 Uppsala feb 30 13 Uppsala mar 40 14 Uppsala apr 60 15 Uppsala may 30
Il semble que s'il y a des égalités, toutes les valeurs liées sont incluses dans la sommation. Je voulais seulement compter 3 instances uniques avec les valeurs les plus élevées.
Toute aide serait très appréciée! :)
4 Réponses :
Nous pouvons faire un distinct
pour supprimer les éléments en double. Le fonctionnement de top_n
est que si les valeurs sont dupliquées, il conservera autant de lignes de dupe
my_data <- structure(list(city = c("Lund", "Lund", "Lund", "Lund", "Lund", "Stockholm", "Stockholm", "Stockholm", "Stockholm", "Stockholm", "Uppsala", "Uppsala", "Uppsala", "Uppsala", "Uppsala"), month = c("jan", "feb", "mar", "apr", "may", "jan", "feb", "mar", "apr", "may", "jan", "feb", "mar", "apr", "may"), number = c(12L, 12L, 18L, 28L, 28L, 15L, 15L, 30L, 30L, 10L, 22L, 30L, 40L, 60L, 30L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"))
En fonction de la La nouvelle sortie d'OP, après la sortie top_n
(qui n'est pas arrange
d), récupère le 'nombre' par ordre décroissant et obtient la somme
sur les 3 premiers "nombre"
my_data %>% group_by(city) %>% top_n(3, number) %>% arrange(city, desc(number)) %>% summarise(number = sum(head(number, 3))) # A tibble: 3 x 2 # city number # <chr> <int> #1 Lund 74 #2 Stockholm 75 #3 Uppsala 130
my_data %>% distinct(city, number, .keep_all = TRUE) %>% group_by(city) %>% top_n(3, number) %>% summarise(top_nr = sum(number))
Merci @akrun mais quand j'exécute votre code suggéré, je reçois
Pourquoi utiliser head
ici? J'ai essayé quelque chose de similaire et j'ai obtenu des résultats étranges.
@NelsonGon Sur la base de la nouvelle sortie, l'OP n'élimine pas les dupes, mais ne prend que les 3 premiers, top_n donne autant de lignes qu'il y a de dupes
Ah, je vois. Merci pour l'explication.
@akrun belle solution! Merci!
Merci @akrun mais quand j'exécute votre code suggéré, j'obtiens: pour Lund 58 qui est un résumé de 28, 18 et 12. Ce que je voulais, c'était un moyen de résumer pour Lund 28 + 28 + 18 = 74. (Je vois que j'ai fait une erreur ci-dessus dans ma description initiale, désolé pour cela). Voici à quoi devrait ressembler le résultat attendu (souhaité):
# A tibble: 3 x 2 city top_nr <chr> <dbl> 1 Lund 74 2 Stockholm 75 3 Uppsala 130
Cette solution tidyverse
(en fait, dplyr
) est presque égale à akrun , mais filtre
est le dataframe à la place d'obtenir le top_n
.
library(tidyverse) my_data %>% group_by(city) %>% arrange(desc(number), .by_group = TRUE) %>% filter(row_number() %in% 1:3) %>% summarise(top_nr = sum(number)) ## A tibble: 3 x 2 # city top_nr # <chr> <int> #1 Lund 74 #2 Stockholm 75 #3 Uppsala 130
La vie pourrait être bien plus simple sans top_n()
:
dat %>% group_by(city) %>% summarize( top_nr = sum(tail(sort(number), 3)) )
Hou la la! Très succinct! Mais en tant que R-amateur, je trouve la partie: sum (tail (sort (number), 3)), assez difficile à comprendre (même si cela réglait vraiment le problème).
En partant du milieu, il tri
le numéro
dans ordre croissant ; après cela, tail
renvoie les 3 derniers nombres du résultat précédent, et passe ces nombres dans la fonction sum
, qui les additionne.
Agréable! Merci! :)
Votre exemple et les numéros de sortie affichés semblent être différents. Est-ce sur un ensemble de données différent
Veuillez utiliser
dput
pour fournir vos données afin qu'il soit plus facile de reproduire le problème.@NelsonGon Je ne connaissais pas la fonction dput. Je vais l'utiliser à l'avenir.