Подсчитать количество строк в каждой группе

У меня есть dataframe, и я хотел бы подсчитать количество строк в каждой группе. Я регулярно использую функцию 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))

Ответ 1

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

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

Ответ 2

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

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

и aggregate, следуя @GregSnow:

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

Ответ 3

Пакет 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()

Ответ 4

Старый вопрос без решения data.table. Итак, здесь идет...

Используя .N

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

Ответ 5

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

Ответ 6

Альтернативой функции 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),]

Ответ 7

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

df1["Count"] <-1

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

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

Ответ 8

Если вы хотите включить 0 отсчетов за месячные годы, которые отсутствуют в данных, вы можете использовать небольшую магию table.

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

Например, игрушка data.frame в вопросе df1 не содержит наблюдений за январь 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

Базовая aggregate функция R не возвращает наблюдение за январь 2014 года.

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

Если вы хотите получить наблюдение за этим месяцем-годом с числом 0, то приведенный выше код вернет data.frame со счетчиками для всех комбинаций месяца и года:

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

Ответ 9

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

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)

Ответ 10

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

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

Ответ 11

Учитывая ответ @Ben, R df1 ошибку, если df1 не содержит столбец x. Но его можно решить элегантно с помощью paste:

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

Аналогично, он может быть обобщен, если в группировке используется более двух переменных:

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

Ответ 12

Вы можете использовать by функциям, как by(df1$Year, df1$Month, count), который будет производить список необходимой агрегации.

Результат будет выглядеть следующим образом:

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
> 

Ответ 13

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

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

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

Ответ 14

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)