【问题标题】:How to lag multiple specific columns of a data frame in R如何在R中滞后数据框的多个特定列
【发布时间】:2021-04-21 17:25:24
【问题描述】:

我想在 R 中滞后数据框的多个特定列。

让我们举这个通用的例子。假设我已经定义了我需要滞后的数据框的哪些列:

Lag <- c(0, 1, 0, 1)
Lag.Index <- is.element(Lag, 1)
df <- data.frame(x1 = 1:8, x2 = 1:8, x3 = 1:8, x4 = 1:8)

我的初始数据框:

        x1  x2  x3  x4   
    1   1   1   1   1
    2   2   2   2   2
    3   3   3   3   3
    4   4   4   4   4 
    5   5   5   5   5
    6   6   6   6   6
    7   7   7   7   7
    8   8   8   8   8 

我想计算以下数据框:

        x1  x2  x3  x4   
    1   1   NA  1   NA
    2   2   2   2   2
    3   3   3   3   3
    4   4   4   4   4 
    5   5   5   5   5
    6   6   6   6   6
    7   7   7   7   7
    8   8   8   8   8 

我会知道如何只为一个滞后列执行此操作,如 here 所示,但无法找到一种方法以优雅的方式为多个滞后列执行此操作。非常感谢任何帮助。

【问题讨论】:

    标签: r dataframe lag


    【解决方案1】:

    您可以使用purrrmap2_dfc 按列滞后不同的值。

    purrr::map2_dfc(df, Lag, dplyr::lag)
    
    #     x1    x2    x3    x4
    #  <int> <int> <int> <int>
    #1     1    NA     1    NA
    #2     2     1     2     1
    #3     3     2     3     2
    #4     4     3     4     3
    #5     5     4     5     4
    #6     6     5     6     5
    #7     7     6     7     6
    #8     8     7     8     7
    

    或者data.table

    library(data.table)
    setDT(df)[, names(df) := Map(shift, .SD, Lag)]
    

    【讨论】:

    • 非常感谢。这两种解决方案都很明亮,完全符合我的需求。我不是 R 方面的专家,请您详细说明 .SD 在这里做什么?
    • .SD 特定于 data.table 这里它指的是df 中的所有列。我们可以将SDcols 指定为.SDcols = 1:3,在这种情况下.SD 将仅引用第1 到第3 列。
    【解决方案2】:

    不确定这是否足够优雅,但我会使用 dplyr 的 mutate_at 函数来调整列

    df %>% dplyr::mutate_at(.vars = vars(x2,x4),.funs = ~lag(., default = NA))
    
    

    【讨论】:

      【解决方案3】:

      我们将lag转换为logical类,得到对应的names,并从dplyr使用across

      library(dplyr)
      df %>% 
            mutate(across(names(.)[as.logical(Lag)], lag))
      #  x1 x2 x3 x4
      #1  1 NA  1 NA
      #2  2  1  2  1
      #3  3  2  3  2
      #4  4  3  4  3
      #5  5  4  5  4
      #6  6  5  6  5
      #7  7  6  7  6
      #8  8  7  8  7
      

      或者我们可以在base R这样做

      df[as.logical(Lag)] <- rbind(NA, df[-nrow(df), as.logical(Lag)])
      

      【讨论】:

        【解决方案4】:

        使用shiftVectorizedata.table 选项

        > setDT(df)[, Vectorize(shift)(.SD, Lag)]
             x1 x2 x3 x4
        [1,]  1 NA  1 NA
        [2,]  2  1  2  1
        [3,]  3  2  3  2
        [4,]  4  3  4  3
        [5,]  5  4  5  4
        [6,]  6  5  6  5
        [7,]  7  6  7  6
        [8,]  8  7  8  7
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-18
          • 1970-01-01
          • 2020-06-23
          相关资源
          最近更新 更多