web-dev-qa-db-fra.com

dplyr n_distinct avec condition

En utilisant dplyr pour résumer un jeu de données, je souhaite appeler n_distinct pour compter le nombre d’occurrences uniques dans une colonne. Cependant, je veux aussi faire un autre summary () pour toutes les occurrences uniques dans une colonne où une condition dans une autre colonne est satisfaite.

Exemple de dataframe nommé "a":

A B
1 Y
2 N
3 Y
1 Y

a %>% summarise(count = n_distinct(A))

Cependant, je souhaite également ajouter un nombre de n_distinct(A)B == "Y"

Le résultat devrait être:

count
    3

lorsque vous ajoutez la condition, le résultat devrait être:

count
    2

Le résultat final que j'essaie d'obtenir est que les deux déclarations sont fusionnées en un appel qui me donne un résultat tel que

count_all  count_BisY
        3           2

Quelle est la manière appropriée de procéder avec dplyr?

8
Ryan Castner

Une alternative consiste à utiliser la fonction uniqueN de data.table inside dplyr :

library(dplyr)
library(data.table)
a %>% summarise(count_all = n_distinct(A), count_BisY = uniqueN(A[B == 'Y']))

qui donne:

  count_all count_BisY
1         3          2

Vous pouvez aussi tout faire avec data.table :

library(data.table)
setDT(a)[, .(count_all = uniqueN(A), count_BisY = uniqueN(A[B == 'Y']))]

ce qui donne le même résultat.

7
Jaap

Cela produit les comptes A distincts pour chaque valeur de B en utilisant dplyr.

library(dplyr)
a %>%
  group_by(B) %>%
  summarise(count = n_distinct(A))

Cela produit le résultat:

Source: local data frame [2 x 2]

       B count
  (fctr) (int)
1      N     1
2      Y     2

Pour produire la sortie souhaitée ajoutée ci-dessus à l'aide de dplyr, vous pouvez procéder comme suit:

a %>% summarise(count_all = n_distinct(A), count_BisY = length(unique(A[B == 'Y'])))

Cela produit le résultat:

  count_all count_BisY
1         3          2
6
Gopala

Filtrer le cadre de données avant d'exécuter les travaux de synthèse

a %>%
  filter(B=="Y") %>%
  summarise(count = n_distinct(A))
3
C_Z_

Nous pouvons également utiliser aggregate à partir de base R

 aggregate(cbind(count=A)~B, a, FUN=function(x) length(unique(x)))
 #  B count
 #1 N 1
 #2 Y 2

Basé sur le résultat attendu du PO

 data.frame(count=length(unique(a$A)), 
            count_BisY = length(unique(a$A[a$B=="Y"])))
1
akrun