web-dev-qa-db-fra.com

Obtenez le nombre de doublons de manière lisible

Je suis nouveau en utilisant dplyr, je dois calculer les valeurs distinctes dans un groupe. Voici un exemple de tableau:

data=data.frame(aa=c(1,2,3,4,NA), bb=c('a', 'b', 'a', 'c', 'c'))

Je sais que je peux faire des choses comme:

by_bb<-group_by(data, bb, add = TRUE)
summarise(by_bb, mean(aa, na.rm=TRUE), max(aa), sum(!is.na(aa)), length(aa))

Mais si je veux le nombre d'éléments uniques?

Je peux faire:

  > summarise(by_bb,length(unique(unlist(aa))))

  bb length(unique(unlist(aa)))
1  a                          2
2  b                          1
3  c                          2

et si je veux exclure les AN, je le fais:

> summarise(by_bb,length(unique(unlist(aa[!is.na(aa)]))))

  bb length(unique(unlist(aa[!is.na(aa)])))
1  a                                      2
2  b                                      1
3  c                                      1

Mais c'est un peu illisible pour moi. Y a-t-il une meilleure façon de faire ce genre de résumé?

46
GabyLP

Que diriez-vous de cette option:

data %>%                    # take the data.frame "data"
  filter(!is.na(aa)) %>%    # Using "data", filter out all rows with NAs in aa 
  group_by(bb) %>%          # Then, with the filtered data, group it by "bb"
  summarise(Unique_Elements = n_distinct(aa))   # Now summarise with unique elements per group

#Source: local data frame [3 x 2]
#
#  bb Unique_Elements
#1  a               2
#2  b               1
#3  c               1

Utilisez filter pour filtrer les lignes où aa a des NA, puis regroupez les données par colonne bb, puis effectuez une synthèse en comptant le nombre d'éléments uniques de la colonne aa par groupe de bb.

Comme vous pouvez le voir, je me sers de l'opérateur de pipe %>% que vous pouvez utiliser pour "diriger" ou "chaîner" des commandes ensemble lorsque vous utilisez dplyr. Cela vous aide à écrire du code facilement lisible, car il est plus naturel, par exemple. vous écrivez le code de gauche à droite et de haut en bas sans être profondément imbriqué de l'intérieur (comme dans l'exemple de code).

Modifier:

Dans la première partie de votre question, vous avez écrit:

Je sais que je peux faire des choses comme:

by_bb<-group_by(data, bb, add = TRUE)
summarise(by_bb, mean(aa, na.rm=TRUE), max(aa), sum(!is.na(aa)), length(aa))

Voici une autre option pour le faire (appliquer un certain nombre de fonctions à la même colonne):

data %>%
  filter(!is.na(aa)) %>%
  group_by(bb) %>%
  summarise_each(funs(mean, max, sum, n_distinct), aa)

#Source: local data frame [3 x 5]
#
#  bb mean max sum n_distinct
#1  a    2   3   4          2
#2  b    2   2   2          1
#3  c    4   4   4          1
99
docendo discimus