Подсчитать количество строк в каждой группе - PullRequest
89 голосов
/ 21 марта 2012

У меня есть фрейм данных, и я хотел бы посчитать количество строк в каждой группе.Я регулярно использую функцию aggregate для суммирования данных следующим образом:

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

Теперь я хотел бы посчитать наблюдения, но не могу найти подходящий аргумент для FUN.Интуитивно я подумал, что это будет выглядеть следующим образом:

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

Но нет такой удачи.

Есть идеи?


Некоторые данные игрушек:

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

Ответы [ 12 ]

54 голосов
/ 21 марта 2012

Следуя совету @ Джошуа, вот один способ подсчитать количество наблюдений в вашем df кадре данных, где Year = 2007 и Month = ноябрь (при условии, что они являются столбцами):

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

и с aggregate, после @GregSnow:

aggregate(x ~ Year + Month, data = df, FUN = length)
45 голосов
/ 05 июня 2013

Текущая лучшая практика (tidyverse):

require(dplyr)
df1 %>% count(Year, Month)

Примечание: оригинальное принятое решение на основе plyr::count было удалено, чтобы избежать путаницы.

34 голосов
/ 13 августа 2015
Пакет

dplyr делает это с помощью команд count / tally или функции n() :

Сначала некоторые данные:

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

Теперь количество:

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

Мы также можем использовать немного более длинную версию с трубопроводами и функцией n():

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

или tally функция:

df %>% 
  group_by(year, month) %>%
  tally()
31 голосов
/ 02 августа 2013

Старый вопрос без решения data.table.Так что вот так ...

Использование .N

library(data.table)
DT <- data.table(df)
DT[, .N, by = list(year, month)]
21 голосов
/ 21 марта 2012

Простая опция для использования с aggregate - это функция length, которая даст вам длину вектора в подмножестве. Иногда немного более надежно использовать function(x) sum( !is.na(x) ).

16 голосов
/ 02 августа 2013

Создайте новую переменную Count со значением 1 для каждой строки:

df1["Count"] <-1

Затем агрегируйте кадр данных, суммируя по столбцу Count:

df2 <- aggregate(df1[c("Count")], by=list(year=df1$year, month=df1$month), FUN=sum, na.rm=TRUE)
16 голосов
/ 22 марта 2012

Альтернативой функции aggregate() в этом случае будет table() с as.data.frame(), которая также будет указывать, какие комбинации года и месяца связаны с нулевыми вхождениями

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

А без встречающихся комбинаций

myAns[which(myAns$Freq>0),]
4 голосов
/ 05 января 2015

Для своих агрегаций я обычно хочу увидеть среднее значение и «насколько велика эта группа» (она же длина).Так что это мой удобный фрагмент для тех случаев;

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)
3 голосов
/ 29 мая 2018

A решение с использованием пакета sqldf:

library(sqldf)
sqldf("SELECT Year, Month, COUNT(*) as Freq
       FROM df1
       GROUP BY Year, Month")
0 голосов
/ 17 мая 2019

Здесь уже есть много замечательных ответов, но я хотел бы добавить еще 1 опцию для тех, кто хочет добавить новый столбец к исходному набору данных, который содержит количество повторений этой строки.

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

То же самое можно сделать, комбинируя любой из приведенных выше ответов с функцией merge().

...