我制作了一个数据框,其中有一列包含日期和一列包含数值。我希望这个数据框按月进行分组,并汇总每个相应月份其他列中的所有数值。
这是我的数据框示例:
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
您可以在
%Y-%m
中将日期提取为 group_by()
格式,并使用 summarise_if()
或 summarise_at()
选择要求和的变量。
(确认
capture.date
是Date
类)
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
范围动词(
_if
u2060、_at
u2060、_all
u2060)已被现有动词中的pick()
或across()
所取代。
df %>%
group_by(Date = strftime(capture.date, "%Y-%m")) %>%
summarise(across(where(is.numeric), sum))
以下应该有效
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
之外的其他函数以获得真实数据。
1) dplyr/zoo 使用末尾注释中可重复显示的数据将每个日期转换为yearmon 类,该类表示没有日期的日期,然后汇总数字列:
library(dplyr)
library(zoo)
df %>%
group_by(yearmon = as.yearmon(capture.date)) %>%
summarize_if(is.numeric, sum) %>%
ungroup
给出这个小标题:
# 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)