web-dev-qa-db-fra.com

résumer les comptes d'un facteur avec dplyr

Je veux grouper une trame de données par une colonne (propriétaire) et sortir une nouvelle trame de données qui compte les nombres de chaque type de facteur à chaque observation. Le bloc de données réel est assez volumineux et il existe 10 facteurs différents.

Voici un exemple d'entrée:

library(dplyr)
df = tbl_df(data.frame(owner=c(0,0,1,1), obs1=c("quiet", "loud", "quiet", "loud"), obs2=c("loud", "loud", "quiet", "quiet")))

  owner  obs1  obs2
1     0 quiet  loud
2     0  loud  loud
3     1 quiet quiet
4     1  loud quiet

Je cherchais une sortie qui ressemble à ceci:

out = data.frame(owner=c("0", "0", "1", "1"), observation=c("obs1", "obs2", "obs1", "obs2"), quiet=c(1, 0, 1, 2), loud=c(1, 2, 1, 0))

  owner observation quiet loud
1     0        obs1     1    1
2     0        obs2     0    2
3     1        obs1     1    1
4     1        obs2     2    0

La fusion me fait à mi-chemin:

melted = tbl_df(melt(df, id=c("owner")))

  owner variable value
1     0     obs1 quiet
2     0     obs1  loud
3     1     obs1 quiet
4     1     obs1  loud
5     0     obs2  loud
6     0     obs2  loud
7     1     obs2 quiet
8     1     obs2 quiet

Mais quelle est la dernière étape? Si "valeur" était un chiffre, j'irais simplement:

melted %>% group_by(owner, variable) %>% summarise(counts=sum(value))

Merci beaucoup!

16
Rory Kirchner

Vous pouvez utiliser tidyr avec dplyr

library(dplyr)
library(tidyr)

 df %>%
 gather(observation, Val, obs1:obs2) %>% 
 group_by(owner,observation, Val) %>% 
 summarise(n= n()) %>%
 ungroup() %>%
 spread(Val, n, fill=0)

ce qui donne la sortie

  #    owner observation loud quiet
  #1     0        obs1    1     1
  #2     0        obs2    2     0
  #3     1        obs1    1     1
  #4     1        obs2    0     2
25
akrun

En 2017, la réponse est

library(dplyr)
library(tidyr)

gather(df, key, value, -owner) %>%
  group_by(owner, key, value) %>%
  tally %>% 
  spread(value, n, fill = 0)

Ce qui donne une sortie

Source: local data frame [4 x 4]
Groups: owner, key [4]

  owner   key  loud quiet
* <dbl> <chr> <dbl> <dbl>
1     0  obs1     1     1
2     0  obs2     2     0
3     1  obs1     1     1
4     1  obs2     0     2
27
Sam Clifford

Si vous vouliez renoncer au dplyr, vous pouvez vous diviser en listes.

df <- split(df, list(df[[obs1]], df[[obs2]])

Si vous vouliez le count, il vous suffit de créer un appel sapply ou lapply pour parcourir les listes et obtenir le nombre de chacune. Ou littéralement toute autre fonction que vous souhaitez.

3
black_sheep07