12

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

     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, ]

它很快,但对我来说似乎有点容易出错。我想知道使用 , 或任何其他包是否有更好的data.table选择dplyr。非常感谢!


Stata中,一个人会这样做:

    tsset id date
    gen value_lagged=L.value
4

4 回答 4

10

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

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
于 2014-09-03T18:53:47.597 回答
7

在由定义的tlag 组内使用函数id

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))
于 2014-09-29T20:21:25.887 回答
7

使用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

这是你想法的变体。诀窍是is.na()直接使用 ini并使用.SDinj而不是DT. 我使用on=了语法,但同样的想法当然也可以通过设置键来完成。.

于 2015-07-30T21:13:21.353 回答
0

现在,带有collapse函数和. 在此处查看滞后不平衡面板的一般答案。flagfdifffgrowth

现在,在您的特定应用程序中,还有一个罕见的事实,即面板不仅不平衡,而且您的时间变量中有一个缺失值,这意味着您不知道观察记录的时间段。在这种情况下,仅应用是collapse::flag行不通的,但您可以生成一个新的 id 变量,将缺失值与collapse::seqid. 所以我的解决方案是:

library(collapse)  
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))

settransform(DF, l_value = flag(value, 1, g = seqid(date, order(id, date)), t = date))
DF
#>   id date value l_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

reprex 包于 2021-07-10 创建(v0.3.0)

我很有信心这仍然比 快data.table,但我还没有测试过。同样,这个数据是相当奇怪的,对于大多数面板不平衡但记录都由 id 和 time 标识的情况,一个简单的flag(value, 1, id, as.integer(date))就可以了,并且很快就会引人注目。请注意,您可以通过确保时间变量为整数来提高效率,因为flag将强制非整数时间变量转换为因子,这也可以消除不规则性。

于 2021-07-10T18:30:29.553 回答