2012-08-07 20 views
6

Sto tentando di replicare una tabella utilizzata spesso nelle statistiche ufficiali ma finora non ha avuto esito positivo. Dato un dataframe come questo:con diverse variabili in 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) 

vorrei creare una tabella che mostra l'anno, il numero di tutti gli studenti (tutti) e quelli che sono di sesso femminile, coloro che hanno partecipato e quelli che passavano. Si prega di notare che "di cui" sotto si riferisce a tutti gli studenti.

Un tavolo che ho in mente sarebbe quella faccia:

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]) 

Sono sicuro che ci sia un modo migliore per questo genere di cose in R.

Nota: ho visto soluzioni lattice, ma non sto usando questo funzionerà per me in quanto ho bisogno di esportare la tabella in Excel.

Grazie in anticipo

risposta

8

Uso plyr:

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

che dà:

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

grazie. Molte grazie. Ho sicuramente intenzione di imparare plyr. – user1043144

+0

Buona risposta ma un minuto dopo @csgillespie. –

+0

@Jilber, penso che intendevi * un minuto prima *. Non ci dovrebbe essere "ma" nel tuo commento. – A5C1D2H2I1M1N2O1R2T1

4

Il pacchetto plyr è grande per questo genere di cose. Primo carico il pacchetto

library(plyr) 

Poi usiamo la funzione 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")) 

Fondamentalmente, aspetta ddply un dataframe come input e restituisce un frame di dati. Abbiamo quindi diviso il frame dei dati di input per ExamenYear. Su ogni sottotabella calcoliamo alcune statistiche riassuntive. Si noti che in ddply, non è necessario utilizzare la notazione $ quando ci si riferisce alle colonne.

+0

Grazie. entrambi avete reso la mia giornata – user1043144

4

Ci avrebbe potuto essere un paio di modifiche (utilizzare with per ridurre il numero di df$ chiamate e utilizzare gli indici di caratteri per migliorare auto-documentazione) al codice che avrebbero reso più facile da leggere e un degno concorrente al ddply soluzioni:

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 

mi aspetterei questo per essere molto più veloce rispetto alla soluzione ddply, anche se questo sarà evidente solo se si sta lavorando su set di dati più grandi.

1

Si consiglia inoltre di dare un'occhiata del prossimo iteratore del plyr: dplyr

Si utilizza una sintassi ggplot-like e fornire prestazioni veloci scrivendo pezzi chiave in C++.

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