R:汇总每月行数

问题描述 投票:0回答: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
r dplyr aggregate
3个回答
3
投票

您可以在

%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))

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
之外的其他函数以获得真实数据。


3
投票

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)
© www.soinside.com 2019 - 2024. All rights reserved.