在 R 中生成移动和变量
Posted
技术标签:
【中文标题】在 R 中生成移动和变量【英文标题】:Generating a moving sum variable in 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
包。与aggregate
、data.table
或ddply
结合使用,您应该进行设置。
【参考方案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
是输入的三列数据框,则使用来自动物园的ave
和rollapplyr
。请注意,我们使用 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
【讨论】:
以上是关于在 R 中生成移动和变量的主要内容,如果未能解决你的问题,请参考以下文章