2012-06-04 18 views
16

Ho due colonne in frame di daticonteggio Frequenza di due colonne in R

2010 1 
2010 1 
2010 2 
2010 2 
2010 3 
2011 1 
2011 2 

voglio contare la frequenza di entrambe le colonne e ottenere il risultato in questo formato

y m Freq 
2010 1 2 
2010 2 2 
2010 3 1 
2011 1 1 
2011 2 1 
+3

Non capisco perché questo non è stato offerto, ma si potrebbe anche solo fare 'as.data.frame (tabella (df))' –

+0

L'unico problema con questa soluzione è una vera tabella a campi incrociati, che stampa anche una riga per gli 0. Questo potrebbe esplodere rapidamente se ci sono molti valori m che non sono condivisi dalla maggior parte dei valori y. – pyll

risposta

19

Se i dati sono dataframe df con colonne y e m

library(plyr) 
counts <- ddply(df, .(df$y, df$m), nrow) 
names(counts) <- c("y", "m", "Freq") 
+1

potresti convertire quell'istruzione in SQL per me? Grazie! –

+3

@DMactheDestroyer lol. Prova il tag 'SQL'. – Gregor

+0

@DMactheDestroyer [vedi sotto risposta, usando sqldf] (https://stackoverflow.com/a/10879629). – zx8754

3

Uso sqldf:

sqldf("SELECT y, m, COUNT(*) as Freq 
     FROM table1 
     GROUP BY y, m") 
3

Se si ha una grande cornice di dati con molte colonne o non conosceva i nomi delle colonne di anticipo, qualcosa di simile potrebbe essere utile:

library(reshape2) 
df_counts <- melt(table(df)) 
names(df_counts) <- names(df) 
colnames(df_counts)[ncol(df_counts)] <- "count" 
df_counts  

    y m  count 
1 2010 1  2 
2 2011 1  1 
3 2010 2  2 
4 2011 2  1 
5 2010 3  1 
6 2011 3  0 
2
library(data.table) 

oldformat <- data.table(oldformat) ## your orignal data frame 
newformat <- oldformat[,list(Freq=length(m)), by=list(y,m)] 
6

A più versione data.table idiomatica di risposta di @ ugh sarebbe:

library(data.table) # load package 
df <- data.frame(y = c(rep(2010, 5), rep(2011,2)), m = c(1,1,2,2,3,1,2)) # setup data 
dt <- data.table(df) # transpose to data.table 
dt[, list(Freq =.N), by=list(y,m)] # use list to name var directly 
+0

Non si tratta di corretto o errato. La risposta è corretta ma forse non così idiomatica. Probabilmente dovresti semplicemente proporre una modifica invece di pubblicare una risposta competitiva. –

+0

Ciao @DavidArenburg, grazie per il feedback. Immagino, mi sono sovraeccitato sulla notazione .N in data.table (anche se mi sembra di ricordare che al momento la risposta di Ugh non sembrava funzionare per me). Su suggerimento ho modificato la risposta di ugh e rimuoverò questa, se le modifiche sono accettate. Ho anche cambiato la parte "errata" nella mia risposta. – Richard

+0

@DavidArenburg - Non modificare una risposta per passare a un'alternativa migliore ([vedi linee guida per la revisione del codice] (http://meta.stackexchange.com/questions/155538/what-are-the-guidelines-for-reviewing/ 155539 # 155539)). Richard, creare la tua risposta era la cosa giusta da fare; – Scopey

4

non ho visto un dplyr risposta ancora. Il codice è piuttosto semplice.

library(dplyr) 
rename(count(df, y, m), Freq = n) 
# Source: local data frame [5 x 3] 
# Groups: V1 [?] 
# 
#  y  m Freq 
# (int) (int) (int) 
# 1 2010  1  2 
# 2 2010  2  2 
# 3 2010  3  1 
# 4 2011  1  1 
# 5 2011  2  1 

dati:

df <- structure(list(y = c(2010L, 2010L, 2010L, 2010L, 2010L, 2011L, 
2011L), m = c(1L, 1L, 2L, 2L, 3L, 1L, 2L)), .Names = c("y", "m" 
), class = "data.frame", row.names = c(NA, -7L)) 
Problemi correlati