Подсчитать количество строк в каждой группе
у меня есть фрейм данных, и я хотел бы подсчитать количество строк в каждой группе. Я регулярно использую 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))
11 ответов:
следуя предложению @Joshua, вот один из способов подсчитать количество наблюдений в вашем
df
таблицы данных, гдеYear
= 2007 иMonth
= Nov (предполагая, что это столбцы):nrow(df[,df$YEAR == 2007 & df$Month == "Nov"])
и
aggregate
, после @GregSnow:aggregate(x ~ Year + Month, data = df, FUN = length)
старый вопрос без
data.table
решение. Вот так и вышло...используя
.N
library(data.table) DT <- data.table(df) DT[, .N, by = list(year, month)]
мы также можем использовать
dplyr
.во-первых, некоторые данные:
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()
самый простой вариант для использования с
aggregate
- Этоlength
функция, которая даст вам длину вектора в подмножестве. Иногда немного более надежным является использованиеfunction(x) sum( !is.na(x) )
.
создать новую переменную
Count
со значением 1 для каждой строки:df1["Count"] <-1
затем агрегировать фрейм данных, суммируя по
для моих агрегаций я обычно хочу видеть среднее и "насколько велика эта группа" (a.k.a. length). Так что это мой удобный фрагмент для тех случаев;
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)
A sql решение с помощью
sqldf
пакет:library(sqldf) sqldf("SELECT Year, Month, COUNT(*) as Freq FROM df1 GROUP BY Year, Month")
учитывая ответ @Ben, R выдаст ошибку, если
df1
не содержит . Но это можно решить элегантно сpaste
:aggregate(paste(Year, Month) ~ Year + Month, data = df1, FUN = NROW)
аналогично, он может быть обобщен, если в группировке используется более двух переменных:
aggregate(paste(Year, Month, Day) ~ Year + Month + Day, data = df1, FUN = NROW)