【问题标题】:sum of preceding 12 months in RR中前12个月的总和
【发布时间】:2019-07-12 06:03:09
【问题描述】:

我正在尝试对过去 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

谢谢你!

【问题讨论】:

  • 一种方法是为缺失月份添加数量 = 0 的行,然后使用“rollapply”创建 sum_amt 列以获取移动总和。

标签: r datatable dplyr sum tidyverse


【解决方案1】:

定义一个函数 sumfun ,它接受带有 yearmon 时间索引的动物园系列。 yearmon 类在内部表示一年和一个月,例如 year + 0 表示一月,year + 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

【讨论】:

  • 这太棒了!!它就像魅力一样 :) 非常感谢!!
【解决方案2】:

这是我的建议:

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 始终采用这种格式。如果您添加天数,那么您将遇到闰年而不是闰年的问题。
  2. 如果两个 yyyymm 重复,则不考虑它们的总和。

最后,当没有找到过去 12 个月的日期时,它返回 0 而不是 NA。

最好的

【讨论】:

  • 感谢您的解决方案!!也是解决问题的好办法!
猜你喜欢
  • 2022-08-02
  • 2013-09-16
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 2018-03-01
  • 2019-07-10
  • 1970-01-01
相关资源
最近更新 更多