Ответ 1
Использование функции tlag
внутри групп, определенных id
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))
Я хотел бы создать переменную, содержащую значение переменной в предыдущем году в группе.
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
Использование функции tlag
внутри групп, определенных id
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))
Я бы, вероятно, справился с этим, используя соединение:
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
Используя 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()
непосредственно в i
и использовать .SD
в j
вместо DT
. Я использовал синтаксис on=
, но эту же идею, конечно же, можно сделать, установив ключи..