2012-03-21 24 views
66

Ho un dataframe e vorrei contare il numero di righe all'interno di ogni gruppo. Ho reguarly utilizzare la funzione aggregate per sommare i dati come segue:Contare il numero di righe all'interno di ciascun gruppo

df2 <- aggregate(x ~ Year + Month, data = df1, sum) 

Ora, vorrei contare le osservazioni, ma non riesco a trovare l'argomento appropriato per FUN. Intuitivamente, ho pensato che sarebbe stato il seguente:

df2 <- aggregate(x ~ Year + Month, data = df1, count) 

Ma, senza fortuna del genere.

Qualche idea?


Alcuni dati giocattolo:

set.seed(2) 
df1 <- data.frame(x = 1:20, 
        Year = sample(2012:2014, 20, replace = TRUE), 
        Month = sample(month.abb[1:3], 20, replace = TRUE)) 
+14

'nrow',' NROW', 'length'. .. –

+12

Continuo a leggere questa domanda chiedendo un modo divertente per contare le cose (a differenza dei molti modi non elaborati, immagino). –

+2

@JoshuaUlrich: 'nrow' non ha funzionato per me ma' NROW' e 'length'worked fine. +1 – Prolix

risposta

35

C'è anche df2 <- count(x, c('Year','Month')) (pacchetto plyr)

+0

C'è un modo per aggregare una variabile e fare anche il conteggio (come 2 funzioni in aggregazione: media + conteggio)? Ho bisogno di ottenere la media di una colonna e il numero di righe per lo stesso valore nell'altra colonna – sop

+0

I'd 'cbind' i risultati di' aggregato (Sepal.Length ~ Species, iris, mean) 'e' aggregate (Sepal.Lunghezza . Lunghezza ~ Specie, iris, lunghezza) ' – geotheory

+0

L'ho fatto, ma sembra che ottengo 2 volte ogni colonna tranne quella aggregata; quindi ho fatto un'unione su di loro e sembra essere ok – sop

46

seguito @ suggerimento di Joshua, ecco un modo si potrebbe contare il numero di osservazioni nel vostro df dataframe dove Year = 2007 e Month = novembre (ammesso che sono colonne):

nrow(df[,df$YEAR == 2007 & df$Month == "Nov"]) 

e con aggregate, seguendo @GregSnow:

aggregate(x ~ Year + Month, data = df, FUN = length) 
20

L'opzione semplice da usare con aggregate è la funzione length che vi darà la lunghezza del vettore nel sottoinsieme. A volte un po 'più robusto è usare function(x) sum(!is.na(x)).

14

Un'alternativa alla funzione aggregate() in questo caso sarebbe table() con as.data.frame(), che sarebbe anche indicare quali combinazioni di Anno e mese sono associati a nessuna occorrenza

df<-data.frame(x=rep(1:6,rep(c(1,2,3),2)),year=1993:2004,month=c(1,1:11)) 

myAns<-as.data.frame(table(df[,c("year","month")])) 

E senza le combinazioni zero verificano

myAns[which(myAns$Freq>0),] 
14

Creare una nuova variabile Count con un valore di 1 per ogni riga:

df1["Count"] <-1 

dataframe Poi aggregato, sommando dalla colonna Count:

df2 <- aggregate(df1[c("Count")], by=list(year=df1$year, month=df1$month), FUN=sum, na.rm=TRUE) 
22

Un vecchio questione senza una data.table soluzione. Quindi ecco qui ...

Utilizzando .N

library(data.table) 
DT <- data.table(df) 
DT[, .N, by = list(year, month)] 
2

Per i miei aggregazioni Io di solito finiscono per voler vedere media e "quanto è grande questo gruppo" (lunghezza anche noto come). Quindi questo è il mio utile snippet per quelle occasioni;

agg.mean <- aggregate(columnToMean ~ columnToAggregateOn1*columnToAggregateOn2, yourDataFrame, FUN="mean") 
agg.count <- aggregate(columnToMean ~ columnToAggregateOn1*columnToAggregateOn2, yourDataFrame, FUN="length") 
aggcount <- agg.count$columnToMean 
agg <- cbind(aggcount, agg.mean) 
25

Possiamo anche utilizzare dplyr.

In primo luogo, alcuni dati:

df <- data.frame(x = rep(1:6, rep(c(1, 2, 3), 2)), year = 1993:2004, month = c(1, 1:11)) 

Ora il conteggio:

library(dplyr) 
count(df, year, month) 
#piping 
df %>% count(year, month) 

Si può anche utilizzare una versione leggermente più lungo con tubazioni e la funzione n():

df %>% 
    group_by(year, month) %>% 
    summarise(number = n()) 

o la funzione `tally:

df %>% 
    group_by(year, month) %>% 
    tally() 
-1
lw<- function(x){length(which(df$variable==someValue))} 

agg<- aggregate(Var1~Var2+Var3, data=df, FUN=lw) 

names(agg)<- c("Some", "Pretty", "Names", "Here") 

View(agg) 
0

Considerando risposta @ Ben, R getterebbe un errore se df1 non contiene x colonna. Ma può essere risolto con eleganza paste:

aggregate(paste(Year, Month) ~ Year + Month, data = df1, FUN = NROW) 

Analogamente, può essere generalizzata se si utilizzano più di due variabili nel gruppo:

aggregate(paste(Year, Month, Day) ~ Year + Month + Day, data = df1, FUN = NROW) 
Problemi correlati