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

时间:2015-03-20 17:46:11

标签: r dataframe sum range

我看过许多类似的帖子,但我相信不太复杂的问题,而且似乎无法找到答案。

我有一个> 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)

我需要的是,对于相同名称的条目,在同一年的jan-mar,apr-jun,jul-sep,oct-dec中的日期总和。

这是我理想的输出:

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)

将完全欣赏任何输入,引导我朝着正确的方向前进。 非常感谢你!

2 个答案:

答案 0 :(得分:2)

<强> 1。使用dplyr / zoo

我们可以转换日期&#39;来自&#39;字符&#39;到&#39;日期&#39;,获取&#39;金额的sum&#39;和last的值&#39; date&#39;按列分组&#39; name&#39;和&#39; Qtr&#39; (从将日期&#39;转换为年度季度(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并更改&#39; date&#39;柱。 Qtr列是&#39;字符&#39;由于as.yearqtr(来自错误)不支持dplyr类。 &#39; Qtr&#39;列不在预期的数据集&#39; data2&#39;中。所以,我认为它是否是&#39;字符&#39;并不重要。或者&#39; as.yearqtr&#39;。如果我们不改变日期&#39;列到&#39;日期&#39;类,并在group_by步骤中进行更改,这将产生与&#39; data2&#39;相同的结果。额外的Qtr&#39;列可以删除。

<强> 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的解决方案,并保留了相同的格式&#39; date&#39;与预期的输出数据2&#39;

一样

答案 1 :(得分:1)

以下是一些方法:

1)聚合&amp;动物园

library(zoo)

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

2)data.table&amp;动物园

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非常快。您可以使用data通过引用从setDT创建data.table,以获得更高的性能,但可能更愿意将它们分开,因此我们将它们分开。