Crie colunas a partir de fatores e conte




plyr (2)

Um problema aparentemente fácil está me mantendo muito ocupado.

Eu tenho um quadro de dados:

> df1
  Name Score
1  Ben     1
2  Ben     2
3 John     1
4 John     2
5 John     3

Eu gostaria de criar um resumo da tabela assim:

> df2
  Name Score_1 Score_2 Score_3
1  Ben       1       1       0
2 John       1       1       1

Então o df2 deve (i) mostrar apenas "Names" e (ii) criar colunas a partir dos fatores únicos em "Score" e (iii) contar o número de vezes que uma pessoa recebeu a pontuação.

Eu tentei:

df2 <- ddply(df1, c("Name"), summarise
          ,Score_1 = sum(df1$Score == 1)
          ,Score_2 = sum(df1$Score == 2)
          ,Score_3 = sum(df1$Score == 3))

que produz:

  Name Score_1 Score_2 Score_3
1  Ben       2       2       1
2 John       2       2       1

Então minha tentativa conta incorretamente todas as ocorrências em vez de contar "por grupo"

EDIT: De acordo com os comentários, também tentou reshape (possivelmente apenas fazendo errado):

> reshape(df1, idvar = "Name", timevar = "Score", direction = "wide")
  Name
1  Ben
3 John

Para começar, a coluna "Pontuação" está faltando, mas, pior do que isso, a partir de minha pesquisa sobre reshape , não estou convencido de que vou conseguir uma contagem de cada fator, que é o ponto principal.


Você só precisa fazer pequenas modificações no seu código. Você deve usar .(Name) vez de c("Name") :

ddply(df1, .(Name), summarise,
      Score_1 = sum(Score == 1),
      Score_2 = sum(Score == 2),
      Score_3 = sum(Score == 3))

dá:

  Name Score_1 Score_2 Score_3
1  Ben       1       1       0
2 John       1       1       1

Outras possibilidades incluem:

1. table(df1) como @alexis_laz mencionado nos comments , isso dá:

> table(df1)
       Score
Name   1 2 3
  Ben  1 1 0
  John 1 1 1

2. A função dcast do pacote reshape2 (ou data.table que possui a mesma função dcast ):

library(reshape2) # or library(data.table)
dcast(df1, Name ~ paste0("Score_", Score), fun.aggregate = length) 

dá:

  Name Score_1 Score_2 Score_3
1  Ben       1       1       0
2 John       1       1       1

Nós podemos usar dplyr/tidyr

 library(dplyr)
 library(tidyr)
 df1 %>% 
     group_by(Name) %>%
      mutate(n=1, Score= paste('Score', Score, sep='_')) %>% 
      spread(Score, n, fill=0) 
 #     Name Score_1 Score_2 Score_3
 #  (chr)   (dbl)   (dbl)   (dbl)
 #1   Ben       1       1       0
 #2  John       1       1       1




plyr