【问题标题】:How to get average of lag period in a frequency as a new variable in r如何将频率中的滞后期平均值作为 r 中的新变量
【发布时间】:2017-03-02 00:03:36
【问题描述】:

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

     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 。

提前感谢您的帮助

【问题讨论】:

    标签: r data.table dplyr panel lag


    【解决方案1】:

    一种方法,它不是精致的,所以也许有人(如果我有时间的话)稍后会提供一个更优雅的解决方案:
    首先是将您的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 个完整月)都将返回 NA。

    【讨论】:

    • 感谢您的回答。一切都与我的数据集完美配合。但是我选择了数据表的答案,用 shift 和 reduce。
    • 建议mutate(Value2 = ( lag(Value1, 3) + lag(Value1, 4) + lag(Value1, 5) ) / 3) 在这种情况下不需要select
    【解决方案2】:

    试试动物园的rollapplyrlist(-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" 类。使用该类年/月值排序正确但显示良好。也就是说,

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

    【讨论】:

      【解决方案3】:

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

      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
      

      【讨论】:

        【解决方案4】:

        我们可以试试:

        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
        

        【讨论】:

          猜你喜欢
          • 2012-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-21
          • 1970-01-01
          • 2021-08-13
          • 2022-01-13
          • 1970-01-01
          相关资源
          最近更新 更多