2012-08-07 9 views
6

Estoy tratando de replicar una tabla utilizada a menudo en las estadísticas oficiales, pero hasta ahora no ha tenido éxito. Dada una trama de datos como éste:tabla de frecuencia con varias variables en R

d1 <- data.frame(StudentID = c("x1", "x10", "x2", 
          "x3", "x4", "x5", "x6", "x7", "x8", "x9"), 
      StudentGender = c('F', 'M', 'F', 'M', 'F', 'M', 'F', 'M', 'M', 'M'), 
      ExamenYear = c('2007','2007','2007','2008','2008','2008','2008','2009','2009','2009'), 
      Exam   = c('algebra', 'stats', 'bio', 'algebra', 'algebra', 'stats', 'stats', 'algebra', 'bio', 'bio'), 
      participated = c('no','yes','yes','yes','no','yes','yes','yes','yes','yes'), 
      passed  = c('no','yes','yes','yes','no','yes','yes','yes','no','yes'), 
      stringsAsFactors = FALSE) 

Me gustaría crear una tabla que muestra por año, el número de todos los estudiantes (todos) y los que son mujeres, quienes participaron y los que pasaron. Tenga en cuenta "de qué" a continuación se refiere a todos los estudiantes.

Una tabla que tengo en mente se vería así:

cbind(All = table(d1$ExamenYear), 
    participated  = table(d1$ExamenYear, d1$participated)[,2], 
    ofwhichFemale  = table(d1$ExamenYear, d1$StudentGender)[,1], 
    ofwhichpassed  = table(d1$ExamenYear, d1$passed)[,2]) 

Estoy seguro de que hay una mejor manera de este tipo de cosas en R.

Nota: He visto soluciones de látex, pero no lo uso, esto funcionará para mí, ya que necesito exportar la tabla en Excel.

Gracias de antemano

Respuesta

8

Uso: plyr

require(plyr) 
ddply(d1, .(ExamenYear), summarize, 
     All=length(ExamenYear), 
     participated=sum(participated=="yes"), 
     ofwhichFemale=sum(StudentGender=="F"), 
     ofWhichPassed=sum(passed=="yes")) 

que da:

ExamenYear All participated ofwhichFemale ofWhichPassed 
1  2007 3   2    2    2 
2  2008 4   3    2    3 
3  2009 3   3    0    2 
+0

gracias. Muchas gracias. Definitivamente voy a aprender plyr. – user1043144

+0

Buena respuesta, pero un minuto después que @csgillespie. –

+0

@Jilber, creo que quisiste decir * un minuto antes *. No debería haber "sino" en su comentario. – A5C1D2H2I1M1N2O1R2T1

4

El paquete plyr es ideal para este tipo de cosas. Primera carga el paquete

library(plyr) 

A continuación, utilizar la función ddply:

ddply(d1, "ExamenYear", summarise, 
     All = length(passed),##We can use any column for this statistics 
     participated = sum(participated=="yes"), 
     ofwhichFemale = sum(StudentGender=="F"), 
     ofwhichpassed = sum(passed=="yes")) 

Básicamente, ddply espera una trama de datos como entrada y devuelve una trama de datos. Luego dividimos el marco de datos de entrada por ExamenYear. En cada subtabla calculamos algunas estadísticas de resumen. Observe que en ddply, no tenemos que usar la notación $ al hacer referencia a las columnas.

+0

Gracias. ustedes dos hicieron mi día – user1043144

4

No podría haber sido un par de modificaciones (utilizar with para reducir el número de df$ llamadas y usar los índices de caracteres para mejorar la auto-documentación) en su código que habrían hecho más fácil la lectura y un competidor digno de la ddply soluciones:

with(d1, cbind(All = table(ExamenYear), 
    participated  = table(ExamenYear, participated)[,"yes"], 
    ofwhichFemale  = table(ExamenYear, StudentGender)[,"F"], 
    ofwhichpassed  = table(ExamenYear, passed)[,"yes"]) 
    ) 

    All participated ofwhichFemale ofwhichpassed 
2007 3   2    2    2 
2008 4   3    2    3 
2009 3   3    0    2 

yo esperaría que esto es mucho más rápido que la solución ddply, a pesar de que sólo será evidente si se está trabajando en grandes conjuntos de datos.

1

También puede echar un vistazo al lado del iterador del plyr: dplyr

Se utiliza una sintaxis similar a ggplot y proporcionar un rendimiento rápido escribiendo piezas clave en C++.

d1 %.% 
group_by(ExamenYear) %.%  
summarise(ALL=length(ExamenYear), 
      participated=sum(participated=="yes"), 
      ofwhichFemale=sum(StudentGender=="F"), 
      ofWhichPassed=sum(passed=="yes"))