R前12个月的总和

时间:2019-02-18 19:45:17

标签: r datatable dplyr sum tidyverse

我正在尝试汇总过去12个月内的行。

df<- read.table(header=T, text='yyyymm      amount
200809  261900
200810  149000
200908  120000
201104  81500
201107  30000
201112  75000
201306  56000
201310  98000
201311  40000
201402  95000
201408  28900
201505  33000
201511  65000
201601  78000
201610  50000
201701  50000
201711  81500')

例如,对于第一行(200809 == 2008年9月),我没有过去12个月内的任何先前数据,因此我要创建的新变量(sum_amt)最终为sum_amt = NA 。对于第二行,我有一个记录是在200810的过去12个月内(即200710和200809之间),所以sum_amt = 261999。同样,对于第三行,我有两条记录在200908年的12个月内,所以sum_amt = 410900(261900 + 261900),依此类推。

最终结果将是:

yyyymm  amount  sum_amt
200809  261900  NA
200810  261900  261900
200908  120000  410900
201104  81500   NA
201107  30000   81500
201112  75000   111500
201306  56000   NA
201310  98000   56000
201311  40000   154000
201402  95000   194000
201408  28900   233000
201505  33000   28900
201511  65000   33000
201601  78000   98000
201610  50000   143000
201701  50000   128000
201711  81500   50000

谢谢你!

2 个答案:

答案 0 :(得分:2)

定义一个函数sumfun,该函数接受具有yearmon时间索引的动物园系列。 yearmon类内部表示年和月,如1月的年份+ 0、2月的年份+ 1/12,依此类推,因此从yearmon对象中减去1可返回一年。 sumfun返回上一年的金额之和;如果当前分数之前没有分数,则返回NA。然后将df读入动物园系列amount中,并使用sumfun对它进行滚动总和。最后转换回数据框。

library(zoo)

sumfun <- function(x) {
  y <- x[time(x) < end(x) & time(x) >= end(x) - 1]
  if (length(y) == 0) NA else sum(y)
}

amount <- read.zoo(df, FUN = function(x) as.yearmon(paste(x), "%Y%m"))
sum12 <- rollapplyr(amount, 13, sumfun, partial = TRUE, fill = NA, coredata = FALSE)
fortify.zoo(cbind(amount, sum12), name = names(df)[1])

给予:

     yyyymm amount  sum12
1  Sep 2008 261900     NA
2  Oct 2008 149000 261900
3  Aug 2009 120000 410900
4  Apr 2011  81500     NA
5  Jul 2011  30000  81500
6  Dec 2011  75000 111500
7  Jun 2013  56000     NA
8  Oct 2013  98000  56000
9  Nov 2013  40000 154000
10 Feb 2014  95000 194000
11 Aug 2014  28900 233000
12 May 2015  33000  28900
13 Nov 2015  65000  33000
14 Jan 2016  78000  98000
15 Oct 2016  50000 143000
16 Jan 2017  50000 128000
17 Nov 2017  81500  50000

答案 1 :(得分:1)

这是我的建议:

df<- read.table(header=T, text='yyyymm      amount
200809  261900
                200810  149000
                200908  120000
                201104  81500
                201107  30000
                201112  75000
                201306  56000
                201310  98000
                201311  40000
                201402  95000
                201408  28900
                201505  33000
                201511  65000
                201601  78000
                201610  50000
                201701  50000
                201711  81500')

df <- as.data.table(df)
df[, yyyymmdd:=ymd(paste0(yyyymm,"01"))]
sum_year <- function(origin){
  sum(df[(origin-yyyymmdd)<=366 &(origin-yyyymmdd)>0]$amount)
}
df[, sum_amut:=mapply(sum_year, yyyymmdd)]

这将在两个假设下进行:

  1. yyyymm始终采用这种格式。如果增加天数,则leap年而不是leap年将会有问题。
  2. 如果重复两个yyyymm,则不要将它们视为总和。

最后,如果找不到过去12个月的日期,它将返回0而不是NA。

最佳