2012-03-15 10 views
17

Ho un data.frame e sto cercando di creare una tabella di frequenza che mostri la frequenza dei valori per ogni riga. Così sto iniziando con qualcosa di simile:convertire un frame di dati in una tabella di frequenza specificatamente formattata

d <- data.frame(a=c(1,2,3), b=c(3,4,5), c=c(1,2,5)) 

che assomiglia a questo:

a b c 
    1 3 1 
    2 4 2 
    3 5 5 

Quello che mi piacerebbe davvero creare è un data.frame contingenza o matrice che assomiglia a questo:

1, 2, 3, 4, 5, 6, 7, 8, 9 
2, 0, 1, 0, 0, 0, 0, 0, 0 
0, 2, 0, 1, 0, 0, 0, 0, 0 
0, 0, 1, 0, 2, 0, 0, 0, 0 

La riga superiore è semplicemente una riga di etichetta e non deve necessariamente essere nel risultato finale. Ma lo aggiungo lì per l'illustrazione. Ogni riga mostra le cifre 1: 9 e il numero di volte in cui ogni cifra compare in ogni riga dei dati di partenza.

Non riesco a capirmi un modo semplice per creare questo. Anche se sembra che la funzione table() dovrebbe essere d'aiuto, non riesco a farmi dare l'amore. Qualsiasi aiuto o idee sono apprezzati.

+4

Hai un data.frame pieno di numeri? Quanto velocemente dimentichi, cavalletta ... usa una matrice. –

+0

L'uso di una matrice cambia la risposta? –

+0

Non cambia la risposta di Josh O'Brien perché 'apply' converte automaticamente il primo argomento in una matrice/matrice. Non sono sicuro di Ilya. Per lo più scherzavo comunque. ;-) –

risposta

11

Qui si va:

t(apply(d, 1, tabulate, nbin=9)) 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 2 0 1 0 0 0 0 0 0 
[2,] 0 2 0 1 0 0 0 0 0 
[3,] 0 0 1 0 2 0 0 0 0 

(anche se probabilmente non importa in questa applicazione, tabulate() (che viene utilizzato all'interno del codice per table()) è bello anche per la velocità impressionante con cui esegue i suoi calcoli)


EDIT:. tabulate() non è impostato fino a che fare con 0 o interi negativi. Se volete un altro uno di linea che fa, si potrebbe usare table() però, fare qualcosa di simile:

d <- data.frame(a=c(0,-1,-2), b=c(3,4,5), c=c(1,2,5)) 

t(apply(d, 1, function(X) table(c(X, -9:9)) - 1)) 
    -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 
[1,] 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 
[2,] 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 
[3,] 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 
+0

Decisamente (un'altra) una di quelle gemme semplici di base R. Grazie ancora R-core! –

+0

un modo per renderlo comprensivo di valori zero e negativi? Dopo aver esaminato il mio caso d'uso, quelli sono più importanti di quanto non avessi capito quando ho fatto la semplice domanda. –

+1

@JDLong - Ho aggiunto un one-liner usando 'table()' che si occupa con garbo di interi zero e negativi. Dovresti semplicemente aggiustare il bit '-9: 9' per coprire qualsiasi intervallo a cui sei interessato, e qualsiasi numero al di fuori di tale intervallo sarà comunque incluso nella tabella. Aggiungendo alcune righe preliminari che controllano l'intervallo degli interi nel data.frame originale e impostano l'intervallo nella tabella di output, puoi facilmente racchiuderlo in una piccola funzione per fare ciò che vuoi. Saluti. –

8

un'altra soluzione utilizzando la tabella

library(reshape) 
d <- data.frame(a=c(1,2,3), b=c(3,4,5), c=c(1,2,5)) 
d2 <- melt(d) 
d2$rows <- rep(1:nrow(d), ncol(d)) 
table(d2$rows, d2$value) 
+0

questo ha il netto vantaggio di gestire correttamente zeri e valori negativi che stava per diventare la mia domanda successiva. Molto bella! –

Problemi correlati