【问题标题】:Generating a moving sum variable in R在 R 中生成移动和变量
【发布时间】:2013-07-08 12:51:00
【问题描述】:

我怀疑这是一个有点简单的问题,有多种解决方案,但我在 R 中还是个新手,详尽的搜索并没有找到与我想做的事情相吻合的答案。

由于缺乏更好的术语,我正在尝试为我的数据框中的变量创建“移动总和”。这些将是 3 年和 5 年的总和,滞后一年。因此,1986 年观察的 5 年总和将是 1981、1982、1983、1984 和 1985 年所有先前观察的总和。这是我想做的一个例子,其中总和变量是观察年前五年内所有x 的总和。

country     year      x      x5yrsum
  A         1980      9        NA
  A         1981      3        NA
  A         1982      5        NA
  A         1983      6        NA
  A         1984      9        NA
  A         1985      7        32
  A         1986      9        30
  A         1987      4        36

  .....................

  B         1990      0        NA
  B         1991      4        NA
  B         1992      2        NA
  B         1993      6        NA
  B         1994      3        NA
  B         1995      7        15
  B         1996      0        22

这是不平衡的面板数据。我怀疑ddply 是合适的,但我不知道它的确切编码。

我们将不胜感激。

【问题讨论】:

  • 看看?rollsum 来自zoo 包。与aggregatedata.tableddply 结合使用,您应该进行设置。

标签: r data-manipulation


【解决方案1】:

您可以在ddply 中使用filter(或任何其他实现“split-apply-combine”方法的函数):

library(plyr)
ddply(DF, .(country), transform, 
          x5yrsum2 = as.numeric(filter(x,c(0,rep(1,5)),sides=1)))

#    country year x x5yrsum x5yrsum2
# 1        A 1980 9      NA       NA
# 2        A 1981 3      NA       NA
# 3        A 1982 5      NA       NA
# 4        A 1983 6      NA       NA
# 5        A 1984 9      NA       NA
# 6        A 1985 7      32       32
# 7        A 1986 9      30       30
# 8        A 1987 4      36       36
# 9        B 1990 0      NA       NA
# 10       B 1991 4      NA       NA
# 11       B 1992 2      NA       NA
# 12       B 1993 6      NA       NA
# 13       B 1994 3      NA       NA
# 14       B 1995 7      15       15
# 15       B 1996 0      22       22

【讨论】:

    【解决方案2】:

    如果DF 是输入的三列数据框,则使用来自动物园的averollapplyr。请注意,我们使用 k+1 的宽度,然后从总和中删除第 k+1 个元素,以便将 x 的当前值排除在外,只对剩余的 k 值求和:

    library(zoo)
    
    k <- 5
    roll <- function(x) rollapplyr(x, k+1, function(x) sum(x[-k-1]), fill = NA)
    transform(DF, xSyrsum = ave(x, country, FUN = roll))
    

    给出:

       country year x xSyrsum
    1        A 1980 9      NA
    2        A 1981 3      NA
    3        A 1982 5      NA
    4        A 1983 6      NA
    5        A 1984 9      NA
    6        A 1985 7      32
    7        A 1986 9      30
    8        A 1987 4      36
    9        B 1990 0      NA
    10       B 1991 4      NA
    11       B 1992 2      NA
    12       B 1993 6      NA
    13       B 1994 3      NA
    14       B 1995 7      15
    15       B 1996 0      22
    

    【讨论】:

      【解决方案3】:

      您也可以使用标准包的filter (stats) 做移动和:

      ms=function(x,n=5) as.numeric(stats::filter(x,rep(1, n),method="convolution",sides=1))
      x=c(1,2,3,4,5,6,7,8,9)
      ms(x,5)
      NA NA NA NA 15 20 25 30 35
      

      要进行 1-lag,请在开头插入 NA 并获取元素(或行)的数量:

      ms.1lag=c(NA,ms(x,5))[1:length(x)]
      cbind(x,ms.1lag)
      x ms.1lag
      [1,] 1      NA
      [2,] 2      NA
      [3,] 3      NA
      [4,] 4      NA
      [5,] 5      NA
      [6,] 6      15
      [7,] 7      20
      [8,] 8      25
      [9,] 9      30
      

      如果你经常使用这个,

      ms=function(x,n=5,lag=0)
        c(rep(NA,lag),
          as.numeric(stats::filter(x,rep(1, n),method="convolution",sides=1)))[1:length(x)]
      cbind(x,ms5.1=ms(x,5,1))
            x ms5.1
       [1,] 1    NA
       [2,] 2    NA
       [3,] 3    NA
       [4,] 4    NA
       [5,] 5    NA
       [6,] 6    15
       [7,] 7    20
       [8,] 8    25
       [9,] 9    30
      

      【讨论】:

        猜你喜欢
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        • 2011-01-06
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多