wake-up-neo.com

Zählen Sie die Anzahl der Zeilen in jeder Gruppe

Ich habe ein Datenframe und möchte die Anzahl der Zeilen in jeder Gruppe zählen. Ich verwende regelmäßig die Funktion aggregate, um Daten wie folgt zu summieren:

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

Nun möchte ich die Beobachtungen zählen, scheint aber nicht das richtige Argument für FUN zu finden. Intuitiv dachte ich, dass es so wäre:

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

Aber kein Glück.

Irgendwelche Ideen?


Einige Spielzeugdaten:

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))
85
MikeTP

Es gibt auch df2 <- count(x, c('Year','Month')) (plyr package)

45
geotheory

Dem @ Joshua-Vorschlag folgend, können Sie die Anzahl der Beobachtungen in Ihrem df-Datenrahmen mit Year = 2007 und Month = Nov zählen (vorausgesetzt es handelt sich um Spalten):

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

und mit aggregate nach @GregSnow:

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

Wir können auch dplyr verwenden.

Zunächst einige Daten:

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

Nun die Zählung:

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

Wir können auch eine etwas längere Version mit Piping und der Funktion n() verwenden:

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

oder die tally-Funktion:

df %>% 
  group_by(year, month) %>%
  tally()
32
jeremycg

Eine alte Frage ohne eine data.table-Lösung. Also hier gehts ...

.N verwenden 

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

Die einfache Option für aggregate ist die length-Funktion, die Ihnen die Länge des Vektors in der Teilmenge angibt. Manchmal ist es etwas robuster, function(x) sum( !is.na(x) ) zu verwenden.

21
Greg Snow

Erstellen Sie eine neue Variable Count mit dem Wert 1 für jede Zeile:

df1["Count"] <-1

Aggregieren Sie anschließend den Datenrahmen, indem Sie die Spalte Count summieren:

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

Eine Alternative zur aggregate()-Funktion wäre in diesem Fall table() mit as.data.frame(), die auch angibt, welche Kombinationen aus Year und Month null Vorkommen zugeordnet sind

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

Und ohne die null vorkommenden Kombinationen

myAns[which(myAns$Freq>0),]
15
BenBarnes

Wenn Sie 0 Zählungen für die in den Daten fehlenden Monate und Jahre einschließen möchten, können Sie ein wenig table Magie verwenden.

data.frame(with(df1, table(Year, Month)))

Beispielsweise enthält der in Frage kommende Datenrahmen für Spielzeug, df1, keine Beobachtungen von Januar 2014.

df1
    x Year Month
1   1 2012   Feb
2   2 2014   Feb
3   3 2013   Mar
4   4 2012   Jan
5   5 2014   Feb
6   6 2014   Feb
7   7 2012   Jan
8   8 2014   Feb
9   9 2013   Mar
10 10 2013   Jan
11 11 2013   Jan
12 12 2012   Jan
13 13 2014   Mar
14 14 2012   Mar
15 15 2013   Feb
16 16 2014   Feb
17 17 2014   Mar
18 18 2012   Jan
19 19 2013   Mar
20 20 2012   Jan

Die Basisfunktion R aggregate gibt keine Beobachtung für Januar 2014 zurück.

aggregate(x ~ Year + Month, data = df1, FUN = length)
  Year Month x
1 2012   Feb 1
2 2013   Feb 1
3 2014   Feb 5
4 2012   Jan 5
5 2013   Jan 2
6 2012   Mar 1
7 2013   Mar 3
8 2014   Mar 2

Wenn Sie eine Beobachtung dieses Monat-Jahres mit 0 als Anzahl wünschen, gibt der obige Code einen data.frame mit Anzahl für alle Monat-Jahr-Kombinationen zurück:

data.frame(with(df1, table(Year, Month)))
  Year Month Freq
1 2012   Feb    1
2 2013   Feb    1
3 2014   Feb    5
4 2012   Jan    5
5 2013   Jan    2
6 2014   Jan    0
7 2012   Mar    1
8 2013   Mar    3
9 2014   Mar    2
7
lmo

Für meine Zusammenfassungen möchte ich normalerweise bedeuten, dass sie bedeuten wollen, wie groß diese Gruppe ist (a.k.a. Länge) .. _.

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)
4
maze

Eine sql -Lösung, die das Paket sqldf verwendet:

library(sqldf)
sqldf("SELECT Year, Month, COUNT(*) as Freq
       FROM df1
       GROUP BY Year, Month")
2
M-M

In Anbetracht der Antwort von @Ben würde R einen Fehler auslösen, wenn df1 keine x-Spalte enthält. Es kann aber elegant mit paste gelöst werden:

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

Ebenso kann es verallgemeinert werden, wenn mehr als zwei Variablen zur Gruppierung verwendet werden:

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

Hier gibt es bereits viele wundervolle Antworten, aber ich wollte noch eine Option für diejenigen hinzufügen, die dem ursprünglichen Datensatz eine neue Spalte hinzufügen möchten, die die Anzahl der Wiederholungen dieser Zeile enthält.

df1$counts <- sapply(X = paste(df1$Year, df1$Month), 
                     FUN = function(x) { sum(paste(df1$Year, df1$Month) == x) })

Dasselbe könnte erreicht werden, indem eine der obigen Antworten mit der Funktion merge() kombiniert wird.

0
filups21

Sie können by-Funktionen als by(df1$Year, df1$Month, count) verwenden, um eine Liste der benötigten Aggregation zu erstellen.

Die Ausgabe wird wie folgt aussehen: 

df1$Month: Feb
     x freq
1 2012    1
2 2013    1
3 2014    5
--------------------------------------------------------------- 
df1$Month: Jan
     x freq
1 2012    5
2 2013    2
--------------------------------------------------------------- 
df1$Month: Mar
     x freq
1 2012    1
2 2013    3
3 2014    2
> 
0
helcode