如何使用数据帧R聚合多个月?

如何使用数据帧R聚合多个月?,r,aggregate-functions,R,Aggregate Functions,我需要使用R中的dataframe从原始数据聚合多个月,例如:带有datetime的dataframe包括2017年和2018年 date category amt 1 2017-08-05 A 0.1900707 2 2017-08-06 B 0.2661277 3 2017-08-07 c 0.4763196 4 2017-08-08 A 0.5183718 5 2017-08-09

我需要使用R中的dataframe从原始数据聚合多个月,例如:带有datetime的dataframe包括2017年和2018年

        date category       amt
  1 2017-08-05        A 0.1900707
  2 2017-08-06        B 0.2661277
  3 2017-08-07        c 0.4763196
  4 2017-08-08        A 0.5183718
  5 2017-08-09        B 0.3021019
  6 2017-08-10        c 0.3393616  
我想根据6个月的期限和类别进行汇总:

         period category       sum
1 2017_secondPeriod        A 25.00972
2  2018_firstPeriod        A 25.59850
3 2017_secondPeriod        B 24.96924
4  2018_firstPeriod        B 24.79649
5 2017_secondPeriod        c 20.17096
6  2018_firstPeriod        c 27.01794
我所做的: 1.选择2017年最后6个月,如wise 2018 2.为每个子集添加一个新列以指示期间 3.再次合并2个子集 4.总数的 详情如下:

library(lubridate)
df <- data.frame(
  date = today() + days(1:300),
  category = c("A","B","c"),
  amt = runif(300)
)

df2017_secondHalf <- subset(df, month(df$date) %in% c(7,8,9,10,11,12) & year(df$date) == 2017)
f2018_firstHalf <- subset(df, month(df$date) %in% c(1,2,3,4,5,6) & year(df$date) == 2018)

sum1 <- aggregate(df2017_secondHalf$amt, by=list(Category=df2017_secondHalf$Category), FUN=sum)
sum2 <- aggregate(df2018_firstHalf$amt, by=list(Category=df2018_secondHalf$Category), FUN=sum)

df2017_secondHalf$period <- '2017_secondPeriod'
df2018_firstHalf$period <- '2018_firstPeriod'

aggregate(x = df$amt, by = df[c("period", "category")], FUN = sum)
我试图弄清楚,但不知道如何聚合多个月,例如,3个月或6个月

提前谢谢
有什么建议吗?

这里有一个3行解决方案,不使用任何包。设k为一段时间内的月数。对于半年期,k为6。对于季度年周期,k将是3,等等。如果您想要一位数字就足够了,那么将sprintf格式中的02替换为1,但对于月度来说则不行,因为这些数字必须是两位数字。如果希望sprintf格式与问题完全匹配,请进一步修改它

k <- 6
period <- with(as.POSIXlt(DF$date), sprintf("%d-%02d", year + 1900, (mon %/% k) + 1))
aggregate(amt ~ category + period, DF, sum)
以使用一个数据包为代价,我们可以通过将周期公式替换为以下公式之一来简化季度和月度计算:

library(zoo)

# quarterly
period <- as.yearqtr(DF$date)

# monthly
period <- as.yearmon(DF$date)
注:可复制形式的输入为:

Lines <- "date category       amt
  1 2017-08-05        A 0.1900707
  2 2017-08-06        B 0.2661277
  3 2017-08-07        c 0.4763196
  4 2017-08-08        A 0.5183718
  5 2017-08-09        B 0.3021019
  6 2017-08-10        c 0.3393616"
DF <- read.table(text = Lines)
DF$date <- as.Date(DF$date)

带lubridate和tidyverse dplyr和magrittr

首先,让我们按学期、季度和三个月创建小组

library(tidyverse)
library(lubridate)

df <- df %>% mutate(Semester = semester(date, with_year = TRUE),
                    Quarter = quarter(date, with_year = TRUE),
                    Trimonthly = round_date(date, unit = "3 months" ))
Lubridate的学期将在学期结束后给你1-6月1日或7-8月2日的成绩;quarter对quarter也有类似的作用。 我添加了第三个更基本的round_date函数,您可以在其中以大小和时间单位的形式指定时间范围。它将生成此类时间范围的第一个日期。我故意把它命名为三个月一次,这样你们就可以看到它和四分之一的比较了

Pivot.Semester <- df %>% 
    group_by(Semester, category) %>% 
    summarise(Semester.sum = sum(amt))
Pivot.Quarter <- df %>% 
    group_by(Quarter, category) %>% 
    summarise(Quarter.sum = sum(amt))
Pivot.Trimonthly <- df %>%
    group_by(Trimonthly, category) %>%
    summarise(Trimonthly.sum = sum(amt))
Pivot.Semester
Pivot.Quarter
Pivot.Trimonthly
可选:如果要将汇总数据加入原始DF

df <- df %>% left_join(Pivot.Semester, by = c("category", "Semester")) %>% 
    left_join(Pivot.Quarter, by = c("category", "Quarter")) %>% 
    left_join(Pivot.Trimonthly, by = c("category", "Trimonthly"))
df

谢谢Grothendieck,但是结果和我得到的有点不同。你能检查一下我生成的数据吗?再试一次我曾经修改过它,你很可能在那之前就得到了代码。还要注意的是,要得到我得到的答案,你必须使用我在答案末尾的注释中使用的数据,这些数据来自于问题。嗨,格罗森迪克。谢谢你的快速回复。我使用前三行代码df代替df来检查结果。我在您2017年和2018年的解决方案类别YB 24.62236,27.46779中看到,而我的类别YB 24.96924,24.79649位于我生成的同一数据帧中。类别B的金额分别为0.2661277和0.3021019,因此它们的总和为0.2661277+0.3021019=0.5682296,这就是我显示的。无论如何,我的答案是可复制的——只需将代码复制粘贴到便笺中,然后再将代码粘贴到答案中即可。谢谢G.GrothendieckThx Nicolas。真是太神奇了。但是为什么在聚合之后,行数与之前相同呢。看看结果,我看到每个日期都有聚合。你有什么想法吗?哦,我和左图合并了,把汇总表Pivot.sement,Pivot.Quarter,Pivot.Trimonthly的值加入到你原来的数据框架中。如果你只是想要汇总的数据,不要运行最后一条指令。我不能提高我的投票率,但我想向你表示感谢。很高兴有帮助。请注意,问题中声称的答案与您显示的数据不符。请修复它,使您的输入和输出一致。
df <- df %>% left_join(Pivot.Semester, by = c("category", "Semester")) %>% 
    left_join(Pivot.Quarter, by = c("category", "Quarter")) %>% 
    left_join(Pivot.Trimonthly, by = c("category", "Trimonthly"))
df