R:每月汇总行数据

3

我创建了一个数据框,其中包含一个日期列和几个数值列。我想让这个数据框按月份分组,并对其他列中每个月对应的所有数值进行汇总。

以下是我的数据框示例:

capture.date  Test1  Test2  Test3
2016-03-18      0      1      1
2016-03-18      1      1      1
2016-03-20      2      1      1
2016-04-12      1      0      1

我已经尝试了一些代码:

df %>% 
  group_by(capture.date) %>% 
  summarise_each(funs(sum))

并且:

aggregate(df[2:4], by=df["capture.date"], sum)

但这两种选项返回的数据框以每天的日期为总结,而不是按月份。我该如何使其按月份总结,而不是按天数?

期望输出:

capture.date  Test1  Test2  Test3
2016-03         3      3      3     
2016-04         1      0      1
3个回答

3

您可以在group_by()中将日期提取为%Y-%m格式,并使用summarise_if()summarise_at()选择要进行求和的变量。

(确认capture.dateDate类)

df %>%
  group_by(Date = strftime(capture.date, "%Y-%m")) %>%
  summarise_if(is.numeric, sum)

# # A tibble: 2 x 4
#   Date    Test1 Test2 Test3
#   <chr>   <int> <int> <int>
# 1 2016-03     3     3     3
# 2 2016-04     1     0     1

3
以下内容应该可以奏效。
library(lubridate)
library(tidyverse)

txt <- "capture.date  Test1  Test2  Test3
2016-03-18      0      1      1
2016-03-18      1      1      1
2016-03-20      2      1      1
2016-04-12      1      0      1"

data <- read.table(text = txt, header = TRUE)

data %>% 
  mutate(month = month(capture.date), 
         year = year(capture.date)) %>% 
  group_by(month, year) %>% 
  summarise_if(is.integer, sum) %>%
  ungroup %>%
  mutate("capture.date" = paste(year, str_pad(month, 2, side = "left", pad = "0"), sep = "-")) %>%
  select(capture.date, Test1, Test2, Test3)

这将产生什么结果。
# A tibble: 2 x 4
  capture.date Test1 Test2 Test3
  <chr>        <int> <int> <int>
1 2016-03          3     3     3
2 2016-04          1     0     1

您可能需要更改 summarise_if 函数中的内容,而不是使用 is.integer 作为您实际数据的函数。

我的错,我更新了我的期望输出。日期输出可以像2016-03、2016-04等一样,而不是一个新的月份和年份列吗? - Kak Schoen
1
请参见更新后的文本,尽管Darren Tsai的解决方案更为简洁。 - MSR

3

1) dplyr/zoo 使用结尾处注释中所示的数据,将每个日期转换为年月类别,该类别表示不含日的日期,然后对数值列进行总结:

library(dplyr)
library(zoo)

df %>% 
  group_by(yearmon = as.yearmon(capture.date)) %>% 
  summarize_if(is.numeric, sum) %>%
  ungroup

给出以下 tibble:

# A tibble: 2 x 4
  yearmon   Test1 Test2 Test3
  <yearmon> <int> <int> <int>
1 Mar 2016      3     3     3
2 Apr 2016      1     0     1

2) zoo 这可以通过一个 read.zoo 命令完成。如果您希望得到一个 data.frame 结果,则可以在结果上使用 fortify.zoo:

library(zoo)
read.zoo(df, FUN = as.yearmon, aggregate = sum)

给出这个动物园系列:
         Test1 Test2 Test3
Mar 2016     3     3     3
Apr 2016     1     0     1

2a) 使用magrittr管道的动物园

这也可以使用magrittr(或dplyr)管道来编写:

library(magrittr)
library(zoo)

df %>% read.zoo(FUN = as.yearmon, aggregate = sum)

或者转换为 data.frame

library(magrittr)
library(zoo)

df %>% read.zoo(FUN = as.yearmon, aggregate = sum) %>% fortify.zoo

3) Base R 使用纯粹的Base R提取每个日期的前7个字符,然后以此聚合:

df2 <- transform(df, year.month = substr(capture.date, 1, 7), capture.date = NULL)
aggregate(. ~ year.month, df2, sum)

给定这个数据框:
  year.month Test1 Test2 Test3
1    2016-03     3     3     3
2    2016-04     1     0     1

注意

以可重复的形式输入:

Lines <- "
capture.date  Test1  Test2  Test3
2016-03-18      0      1      1
2016-03-18      1      1      1
2016-03-20      2      1      1
2016-04-12      1      0      1"
df <- read.table(text = Lines, header = TRUE, as.is = TRUE)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接