如何获得频率滞后周期的平均值作为r中的新变量

How to get average of lag period in a frequency as a new variable in r

我正在尝试安排我的面板数据集以使用定期出现的滞后期的平均值来创建新变量。我的示例数据集如下所示,可以使用以下代码访问

     Time ID  Value1 Value2
1  Jan-14  A     12     NA
2  Feb-14  A     14     NA
3  Mar-14  A     15     NA
4  Apr-14  A     18     NA
5  May-14  A     10     NA
6  Jun-14  A     12  13.67
7  Jul-14  A     13  15.67
8  Aug-14  A     14  14.33
9  Jan-14  B     32     NA
10 Feb-14  B     14     NA
11 Mar-14  B     15     NA
12 Apr-14  B     18     NA
13 May-14  B     20     NA
14 Jun-14  B     12  20.33
15 Jul-14  B     13  15.67
16 Aug-14  B     14  17.78

df<-structure(list(Time = structure(c(4L, 3L, 7L, 1L, 8L, 6L, 5L, 
2L, 4L, 3L, 7L, 1L, 8L, 6L, 5L, 2L), .Label = c("Apr-14", "Aug-14", 
"Feb-14", "Jan-14", "Jul-14", "Jun-14", "Mar-14", "May-14"), class = "factor"), 
    ID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"), 
    Value1 = c(12L, 14L, 15L, 18L, 10L, 12L, 13L, 14L, 32L, 14L, 
    15L, 18L, 20L, 12L, 13L, 14L)), .Names = c("Time", "ID", 
"Value1"), class = "data.frame", row.names = c(NA, -16L))

我想创建一个名为 Value2 的新变量,考虑到每次观察对应于前 4-6 个月的 3 个月的平均值(这只是为了举例,我的月度数据集在 40 个人中持续 12 年,而且我将不得不考虑比 3 个月更高的延迟,也许 14 个月)。在这里我还需要考虑 ID,因为需要保留面板结构。 3 个月前未完成的所有观测值,应表示为NA。例如 Jun_14_A 应该得到从 Mar_14_AJan_14_A 的平均值。 (12+14+15)/3 =13.67

我提到了一些例子 here 但这些例子并没有提供我正在寻找的特别滞后平均值,并且在没有前 3 个完整月份时表示为 NA 。

提前感谢您的帮助

一种方法,它没有改进,所以也许有人(如果我有时间的话)稍后会提出一个更优雅的解决方案:
首先是将您的 df$time 转换为实际日期。

library(zoo)
df$Time=as.yearmon(as.character(df$Time),"%b-%y")
library(dplyr)
df%>%
  group_by(ID)%>%
  mutate(Value2 = ( lag(Value1, 3) + lag(Value1, 4) + lag(Value1, 5) ) / 3)

     Time     ID Value1   Value2
   <fctr> <fctr>  <int>    <dbl>
1  Jan-14      A     12       NA
2  Feb-14      A     14       NA
3  Mar-14      A     15       NA
4  Apr-14      A     18       NA
5  May-14      A     10       NA
6  Jun-14      A     12 13.66667
7  Jul-14      A     13 15.66667
8  Aug-14      A     14 14.33333
9  Jan-14      B     32       NA
10 Feb-14      B     14       NA
11 Mar-14      B     15       NA
12 Apr-14      B     18       NA
13 May-14      B     20       NA
14 Jun-14      B     12 20.33333
15 Jul-14      B     13 15.66667
16 Aug-14      B     14 17.66667

我创建了滞后 3、4 和 5 的 3 个变量,并简单地计算平均值,任何 NA(不是 3 个完整月)都将 return NA。

我们可以试试:

library(data.table)
setDT(df)
f <- function(x) if(anyNA(x[1:6])) NA else mean(x[1:3]) 
df[, Value2 := zoo::rollapply(Value1, 6, f, align = "right", partial = TRUE), by = ID]

> df
      Time ID Value1   Value2
 1: Jan-14  A     12       NA
 2: Feb-14  A     14       NA
 3: Mar-14  A     15       NA
 4: Apr-14  A     18       NA
 5: May-14  A     10       NA
 6: Jun-14  A     12 13.66667
 7: Jul-14  A     13 15.66667
 8: Aug-14  A     14 14.33333
 9: Jan-14  B     32       NA
10: Feb-14  B     14       NA
11: Mar-14  B     15       NA
12: Apr-14  B     18       NA
13: May-14  B     20       NA
14: Jun-14  B     12 20.33333
15: Jul-14  B     13 15.66667
16: Aug-14  B     14 17.66667

这是另一种使用 data.table 的方法,它是 shift 函数结合 Reduce (这几乎是对 的欺骗)

library(data.table)
setDT(df)[, Value2 := Reduce(`+`, shift(Value1, 3:5))/3, by = ID]
df
#       Time ID Value1   Value2
#  1: Jan-14  A     12       NA
#  2: Feb-14  A     14       NA
#  3: Mar-14  A     15       NA
#  4: Apr-14  A     18       NA
#  5: May-14  A     10       NA
#  6: Jun-14  A     12 13.66667
#  7: Jul-14  A     13 15.66667
#  8: Aug-14  A     14 14.33333
#  9: Jan-14  B     32       NA
# 10: Feb-14  B     14       NA
# 11: Mar-14  B     15       NA
# 12: Apr-14  B     18       NA
# 13: May-14  B     20       NA
# 14: Jun-14  B     12 20.33333
# 15: Jul-14  B     13 15.66667
# 16: Aug-14  B     14 17.66667

尝试 rollapplyr 来自动物园。 list(-3:-5) 的宽度意味着它将在每次迭代中使用从当前点偏移 -3、-4 和 -5 的组件:

library(zoo)
roll <- function(x) rollapplyr(x, list(-3:-5), mean, fill = NA)
transform(df, Value2 = ave(Value1, ID, FUN = roll))

给出以下数据框:

     Time ID Value1   Value2
1  Jan-14  A     12       NA
2  Feb-14  A     14       NA
3  Mar-14  A     15       NA
4  Apr-14  A     18       NA
5  May-14  A     10       NA
6  Jun-14  A     12 13.66667
7  Jul-14  A     13 15.66667
8  Aug-14  A     14 14.33333
9  Jan-14  B     32       NA
10 Feb-14  B     14       NA
11 Mar-14  B     15       NA
12 Apr-14  B     18       NA
13 May-14  B     20       NA
14 Jun-14  B     12 20.33333
15 Jul-14  B     13 15.66667
16 Aug-14  B     14 17.66667

注意:虽然我们没有做出更改,因为不需要回答问题,但请注意,您可能希望使用 zoo 的 "yearmon" class 第一列。使用 class year/month 值可以正确排序但显示效果很好。即,

transform(df, Time = as.yearmon(Time, "%b-%y"), Value2 = ...as above...)