对于给定的标识符,按日期范围对行求和

Sum rows by date range, for a given identifier

我看了很多类似的帖子,但我认为问题不那么复杂,似乎无法找到答案。

我有 >1000000 行数据,例如这种形式:

date<-c("9/30/2012","10/31/2012","11/30/2012","12/31/2012","1/31/2013","2/28/2013","3/31/2013","10/31/2012","11/30/2012","12/31/2012","1/31/2013","2/28/2013","3/31/2013")
name<-c("a","a","a","a","a","a","a","b","b","b","b","b","b")
amount<-c(100,200,300,400,500,600,700,800,900,800,700,600,500)
data<-data.frame(name,date,amount)
View(data)

我需要的是,对于同名条目,将同一年的一月至三月、四月至六月、七月至九月、十月至十二月的日期相加。

这是我的理想输出:

date2<-c("9/30/2012","12/31/2012","3/31/2013","12/31/2012","3/13/2013")
name2<-c("a","a","a","b","b")
amount2<-c(100,900,1800,2500,1800)
data2<-data.frame(name2,date2,amount2)
View(data2)

非常感谢任何意见,引导我朝着正确的方向前进。 非常感谢!

1.使用 dplyr/zoo

我们可以将'date'class从'character'转换为'Date',得到'amount'和[=13=的sum ] 按列 'name' 和 'Qtr' 分组的 'date' 的值(将 'date' 转换为年度季度 (as.yearqtr)。

library(dplyr)
library(zoo)
 data %>%
     mutate(date=as.Date(date, format='%m/%d/%Y')) %>%
     group_by(name, Qtr=as.character(as.yearqtr(date))) %>% 
     summarise(amount= sum(amount), date=last(date))
 #  name     Qtr amount       date
 #1    a 2012 Q3    100 2012-09-30
 #2    a 2012 Q4    900 2012-12-31
 #3    a 2013 Q1   1800 2013-03-31
 #4    b 2012 Q4   2500 2012-12-31
 #5    b 2013 Q1   1800 2013-03-31

注意: 还添加了@docendo discimus 建议以使用 last 并更改 'date' 列的 class。 Qtr 列是 'character',因为 as.yearqtr class 不受 dplyr 支持(来自错误)。 'Qtr' 列不在预期的数据集 'data2' 中。所以,我猜是 'character' 还是 'as.yearqtr' 都没有关系。如果我们不将 'date' 列更改为 'Date' class,并在 group_by 步骤中进行更改,这将给出与 [=50= 相同的结果].可以删除多余的 'Qtr' 列。

2。不使用动物园

 data %>%
     mutate(date1 = as.Date(date, format = '%m/%d/%Y')) %>% 
     group_by(name, Qtr= sprintf('%s %s', format(date1, '%Y'),
                                         quarters(date1))) %>%
     summarise(amount = sum(amount), date=last(date)) %>%
     ungroup() %>%
     select(-Qtr) %>% 
     as.data.frame()
 #  name amount       date
 #1    a    100  9/30/2012
 #2    a    900 12/31/2012
 #3    a   1800  3/31/2013
 #4    b   2500 12/31/2012
 #5    b   1800  3/31/2013

注意 2: 添加了一个不使用 as.yearqtr 的解决方案,'date' 的格式与预期输出 'data2'

这里有一些方法:

1) 聚合 & 动物园

library(zoo)

aggregate(amount ~ name + yearqtr, 
          transform(data, yearqtr = as.yearqtr(date, "%m/%d/%Y")), 
          sum)

2) data.table & 动物园

library(data.table)
library(zoo)

dt <- data.table(data, key = "name,date")
dt[, date := as.yearqtr(date, "%m/%d/%Y")][, list(sum = sum(amount)), by = "name,date"]

请注意,这两种解决方案都将 date 转换为真正的 "yearqtr" 对象,而不仅仅是字符串。我没有对这些进行基准测试,但通常 data.table 非常快。您可以使用 setDT 通过引用从 data 创建 data.table 以获得更好的性能,但可能更愿意将它们分开,因此我们将它们分开放置在这里。