Crea columnas a partir de factores y cuenta

Un problema aparentemente fácil es mantenerme muy ocupado.

Tengo un dataframe:

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

Me gustaría crear un resumen de la tabla como este:

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

Entonces, df2 debe (i) mostrar únicamente “Nombres” únicos y (ii) crear columnas a partir de los factores únicos en “Puntuación” y (iii) contar la cantidad de veces que una persona recibió dicha calificación.

Yo he tratado:

 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 produce:

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

Entonces, mi bash cuenta incorrectamente todas las ocurrencias en lugar de contar “por grupo”

EDITAR: según los comentarios, también intenté reshape (posiblemente solo hacerlo mal):

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

Para empezar, falta la columna “Puntuación” pero, peor que eso, de mi investigación sobre la reshape , no estoy convencido de que voy a obtener un recuento de cada factor, que es el punto.

Solo necesita hacer una pequeña modificación a su código. Debe usar .(Name) lugar de c("Name") :

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

da:

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

Otras posibilidades incluyen:

1. table(df1) como @alexis_laz mencionado en los comentarios , esto da:

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

2. La función dcast del paquete reshape2 (o data.table que tiene la misma función dcast ):

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

da:

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

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