Ответ 1
Наилучшая текущая практика (tidyverse):
require(dplyr)
df1 %>% count(Year, Month)
У меня есть 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))
Наилучшая текущая практика (tidyverse):
require(dplyr)
df1 %>% count(Year, Month)
Следуя предложению @Joshua, здесь можно было бы подсчитать количество наблюдений в вашем фрейме df
, где Year
= 2007 и Month
= Nov (при условии, что они являются столбцами):
nrow(df[,df$YEAR == 2007 & df$Month == "Nov"])
и aggregate
, следуя @GregSnow:
aggregate(x ~ Year + Month, data = df, FUN = length)
Пакет 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()
Старый вопрос без решения data.table
. Итак, здесь идет...
Используя .N
library(data.table)
DT <- data.table(df)
DT[, .N, by = list(year, month)]
Простой вариант использования с aggregate
- это функция length
, которая даст вам длину вектора в подмножестве. Иногда немного более надежным является использование function(x) sum( !is.na(x) )
.
Альтернативой функции 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),]
Создайте новую переменную Count
со значением 1 для каждой строки:
df1["Count"] <-1
Затем агрегируйте данные, суммируя их по столбцу Count
:
df2 <- aggregate(df1[c("Count")], by=list(Year=df1$Year, Month=df1$Month), FUN=sum, na.rm=TRUE)
Если вы хотите включить 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
Для моих скоплений я обычно хочу увидеть среднее значение и "насколько велика эта группа" (длина 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)
Решение sql с использованием пакета sqldf
:
library(sqldf)
sqldf("SELECT Year, Month, COUNT(*) as Freq
FROM df1
GROUP BY Year, Month")
Учитывая ответ @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)
Вы можете использовать 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
>
Здесь уже есть множество замечательных ответов, но я хотел бы добавить еще 1 опцию для тех, кто хочет добавить новый столбец в исходный набор данных, который содержит количество повторений этой строки.
df1$counts <- sapply(X = paste(df1$Year, df1$Month),
FUN = function(x) { sum(paste(df1$Year, df1$Month) == x) })
То же самое может быть достигнуто путем объединения любого из приведенных выше ответов с функцией merge()
.
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)