2012-03-15 1 views
99

Из фрейма данных существует ли простой способ агрегировать (то есть суммировать) несколько переменных одновременно?Совокупность/суммирование нескольких переменных на группу (т. Е. Сумма, среднее и т. Д.)

Ниже приведены некоторые примеры данных:

library(lubridate) 
days = 365*2 
date = seq(as.Date("2000-01-01"), length = days, by = "day") 
year = year(date) 
month = month(date) 
x1 = cumsum(rnorm(days, 0.05)) 
x2 = cumsum(rnorm(days, 0.05)) 
df1 = data.frame(date, year, month, x1, x2) 

Я хотел бы одновременно агрегировать x1 и x2 переменные из кадра df2 данных в год и месяц. Следующий код суммирует переменную x1, но также возможно одновременно агрегировать переменную x2?

### aggregate variables by year month 
df2=aggregate(x1 ~ year+month, data=df1, sum, na.rm=TRUE) 
head(df2) 

Любые предложения были бы весьма полезными.

+0

@Jaap Этот вопрос не дублируется по следующей ссылке. Это потому, что речь идет о том, что делать с «dplyr». Отмените дублирующийся знак. r - суммирование нескольких столбцов с dplyr? - Переполнение стека https://stackoverflow.com/questions/21644848/summarizing-multiple-columns-with-dplyr – Keiku

ответ

32

Где находится этот год() функция?

Вы также можете использовать пакет reshape2 для выполнения этой задачи:

require(reshape2) 
df_melt <- melt(df1, id = c("date", "year", "month")) 
dcast(df_melt, year + month ~ variable, sum) 
# year month   x1   x2 
1 2000  1 -80.83405 -224.9540159 
2 2000  2 -223.76331 -288.2418017 
3 2000  3 -188.83930 -481.5601913 
4 2000  4 -197.47797 -473.7137420 
5 2000  5 -259.07928 -372.4563522 
+6

Функция 'recast' (также из' reshape2') объединяет функции 'melt' и' dcast' для выполнения следующих задач: 'recast (df1, year + month ~ variable, sum, id.var = c («дата», «год», «месяц»)) ' – Jaap

151

Да, в ваших formula, вы можете cbind числовых переменных агрегатироваться:

aggregate(cbind(x1, x2) ~ year + month, data = df1, sum, na.rm = TRUE) 
    year month   x1   x2 
1 2000  1 7.862002 -7.469298 
2 2001  1 276.758209 474.384252 
3 2000  2 13.122369 -128.122613 
... 
23 2000 12 63.436507 449.794454 
24 2001 12 999.472226 922.726589 

См ?aggregate, в formula аргумент и примеры.

+2

Возможно ли использовать cbind динамические переменные? –

+9

Стоит отметить, что когда какая-либо из переменных, которая находится в cbind, имеет NA, строка будет удалена для каждой переменной в cbind. Это не то поведение, которое я ожидал. –

+0

Что делать, если я вместо x1 и x2 хочу использовать все остальные переменные (кроме года, месяца) –

39

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

https://github.com/Rdatatable/data.table/wiki

library(data.table) 
df2 <- setDT(df1)[, lapply(.SD, sum), by=.(year, month), .SDcols=c("x1","x2")] 
setDF(df2) # convert back to dataframe 

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

require(plyr) 
df2 <- ddply(df1, c("year", "month"), function(x) colSums(x[c("x1", "x2")])) 

Используя обобщать() из пакета Hmisc (заголовки столбцов грязны в моем примере, хотя)

# need to detach plyr because plyr and Hmisc both have a summarize() 
detach(package:plyr) 
require(Hmisc) 
df2 <- with(df1, summarize(cbind(x1, x2), by=llist(year, month), FUN=colSums)) 
25

С dplyr пакета, вы можете использовать summarise_all, summarise_at или summarise_if функции агрегировать несколько переменных одновременно. Для примера набора данных вы можете сделать это следующим образом:

library(dplyr) 
# summarising all non-grouping variables 
df2 <- df1 %>% group_by(year, month) %>% summarise_all(sum) 

# summarising a specific set of non-grouping variables 
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(x1, x2), sum) 
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(-date), sum) 

# summarising a specific set of non-grouping variables based on condition (class) 
df2 <- df1 %>% group_by(year, month) %>% summarise_if(is.numeric, sum) 

В результате последних двух вариантов:

year month  x1   x2 
    <dbl> <dbl>  <dbl>  <dbl> 
1 2000  1 -73.58134 -92.78595 
2 2000  2 -57.81334 -152.36983 
3 2000  3 122.68758 153.55243 
4 2000  4 450.24980 285.56374 
5 2000  5 678.37867 384.42888 
6 2000  6 792.68696 530.28694 
7 2000  7 908.58795 452.31222 
8 2000  8 710.69928 719.35225 
9 2000  9 725.06079 914.93687 
10 2000 10 770.60304 863.39337 
# ... with 14 more rows 

Примечание: summarise_each осуждается в пользу summarise_all, summarise_at и summarise_if.


Как уже упоминалось в my comment above, вы можете также использовать функцию recast из reshape2 -package:

library(reshape2) 
recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month")) 

, который даст вам тот же результат.

Смежные вопросы