首页 文章

在R中的不 balancer 面板数据中创建滞后变量

提问于
浏览
10

我想在一个组中创建一个包含上一年变量值的变量 .

id   date        value
1     1   1992          4.1  
2     1     NA          4.5  
3     1   1991          3.3  
4     1   1990          5.3  
5     1   1994          3.0  
6     2   1992          3.2  
7     2   1991          5.2

如果组中缺少前一年,则应丢失 value_lagged - 因为它是组内的第一个日期(如第4,7行),或者因为数据中存在年份缺口(如第5行) . 此外,当缺少当前时间时,应丢失 value_lagged (如第2行) .

这给出了:

id   date    value    value_lagged  
1     1   1992      4.1             3.3
2     1     NA      4.5              NA
3     1   1991      3.3             5.3
4     1   1990      5.3              NA
5     1   1994      3.0              NA
6     2   1992      3.2             5.2
7     2   1991      5.2              NA

现在,在R中,我使用 data.table

DT = data.table(id    = c(1,1,1,1,1,2,2),
                 date  = c(1992,NA,1991,1990,1994,1992,1991),
                 value = c(4.1,4.5,3.3,5.3,3.0,3.2,5.2)
                )
 setkey(DT, id, date)
 DT[, value_lagged := DT[J(id, date-1), value], ]
 DT[is.na(date), value_lagged := NA, ]

它's fast but it seems somewhat error prone to me. I'想知道是否有更好的替代品使用 data.tabledplyr 或任何其他包 . 非常感谢!


Stata 中,人们可以这样做:

tsset id date
    gen value_lagged=L.value

3 回答

  • 9

    我可能会使用连接解决这个问题:

    library(dplyr)
    
    df <- data.frame(
      id = c(1, 1, 1, 1, 1, 2, 2), 
      date = c(1992, NA, 1991, 1990, 1994, 1992, 1991), 
      value = c(4.1, 4.5, 3.3, 5.3, 3.0, 3.2, 5.2)
    )
    
    
    last_year <- df %>% 
      filter(!is.na(date)) %>%
      mutate(date = date + 1, lagged_value = value, value = NULL)
    
    df %>%
      left_join(last_year)
    #> Joining by: c("id", "date")
    #>   id date value lagged_value
    #> 1  1 1992   4.1          3.3
    #> 2  1   NA   4.5           NA
    #> 3  1 1991   3.3          5.3
    #> 4  1 1990   5.3           NA
    #> 5  1 1994   3.0           NA
    #> 6  2 1992   3.2          5.2
    #> 7  2 1991   5.2           NA
    
  • 6

    id 定义的组内使用 tlag 函数

    library(dplyr)
    tlag <- function(x, n = 1L, time) { 
      index <- match(time - n, time, incomparables = NA)
      x[index]
    }
    
    df %>% group_by(id) %>% mutate(value_lagged = tlag(value, 1, time = date))
    
  • 3

    使用 1.9.5 ,其中连接不需要设置键,可以按如下方式完成:

    require(data.table) # v1.9.5+
    DT[!is.na(date), value_lagged := 
             .SD[.(id = id, date = date - 1), value, on = c("id", "date")]]
    #    id date value value_lagged
    # 1:  1 1992   4.1          3.3
    # 2:  1   NA   4.5           NA
    # 3:  1 1991   3.3          5.3
    # 4:  1 1990   5.3           NA
    # 5:  1 1994   3.0           NA
    # 6:  2 1992   3.2          5.2
    # 7:  2 1991   5.2           NA
    

    这是你的想法的变化 . 诀窍是直接在 i 中使用 is.na() 并在 j 中使用 .SD 而不是 DT . 我使用了 on= 语法,但同样的想法当然可以通过设置键来完成 . .

相关问题