web-dev-qa-db-fra.com

Renvoie la valeur de chaîne la plus fréquente pour chaque groupe

a <- c(rep(1:2,3))
b <- c("A","A","B","B","B","B")
df <- data.frame(a,b)

> str(b)
chr [1:6] "A" "A" "B" "B" "B" "B"

  a b
1 1 A
2 2 A
3 1 B
4 2 B
5 1 B
6 2 B

Je souhaite grouper par variable a et renvoyer la valeur la plus fréquente de b

Mon résultat souhaité ressemblerait à

  a b
1 1 B
2 2 B

Dans dplyr ce serait quelque chose comme

df %>% group_by(a) %>% summarize (b = most.frequent(b))

J'ai mentionné dplyr uniquement pour visualiser le problème.

16
rmuc8

La clé est de commencer à grouper par a et b pour calculer les fréquences, puis de ne prendre que le plus fréquent par groupe de a, par exemple:

df %>% 
  count(a, b) %>%
  slice(which.max(n))

Source: local data frame [2 x 3]
Groups: a

  a b n
1 1 B 2
2 2 B 2

Bien sûr, il existe d'autres approches, il ne s'agit donc que d'une "clé" possible.

23
docendo discimus

by() chaque valeur de a, créez une table() de b et extrayez la names() de la plus grande entrée dans cette table():

> with(df,by(b,a,function(xx)names(which.max(table(xx)))))
a: 1
[1] "B"
------------------------
a: 2
[1] "B"

Vous pouvez envelopper ceci dans as.table() pour obtenir une sortie plus jolie, bien que cela ne corresponde toujours pas exactement au résultat souhaité:

> as.table(with(df,by(b,a,function(xx)names(which.max(table(xx))))))
a
1 2 
B B
3
Stephan Kolassa

Ce qui fonctionne pour moi ou qui est plus simple est:

df %>% group_by(a) %>% slice(which.max(table(b)) )
df %>% group_by(a) %>% count(b) %>% top_n(1)
1
Ferroao