Продолжение от этого вопроса .
У меня есть три таблицы данных (фактическая input
одна намного больше, и производительность имеет значение, поэтому я должен использовать data.table столько, сколько смогу):
input <- fread(" ID | T1 | T2 | T3 | DATE
ACC001 | 1 | 0 | 0 | 31/12/2016
ACC001 | 1 | 0 | 1 | 30/06/2017
ACC002 | 0 | 1 | 1 | 31/12/2016", sep = "|")
mevs <- fread(" DATE | INDEX_NAME | INDEX_VALUE
31/12/2016 | GDP | 1.05
30/06/2017 | GDP | 1.06
31/12/2017 | GDP | 1.07
30/06/2018 | GDP | 1.08
31/12/2016 | CPI | 0.02
30/06/2017 | CPI | 0.00
31/12/2017 | CPI | -0.01
30/06/2018 | CPI | 0.01 ", sep = "|")
time <- fread(" DATE
31/12/2017
30/06/2018 ", sep = "|")
С этим мне нужно достичь 2 вещей:
Вставьте значения GDP
и CPI
из второго dt (mevs
) в первый (input
), чтобы выполнить некоторые вычисления в последнем столбце на основе T1
, T2
, T3
, GDP
и CPI
.
Сделайте прогноз для интервалов времени, указанных в третьем dt (time
), скопировав значения T1
, T2
и T3
в предыдущем интервале в том же ID
(так, ACC001 они останутся 1, 0, 1
), если он существует (заполняя их 0
, если его нет) и получая GDP
и CPI
от соответствующих дат.
Для этого я использую следующие фрагменты кода:
ones <- input[, .N, by = ID][N == 1, ID]
input[, .SD[time, on = "DATE"], by = ID
][dcast(mevs, DATE ~ INDEX_NAME), on = "DATE", `:=` (GDP = i.GDP, CPI = i.CPI)
][, (2:4) := lapply(.SD, function(x) if (.BY %in% ones) replace(x, is.na(x), 0L) else zoo::na.locf(x) )
, by = ID, .SDcols = 2:4][]
Что делает (благодаря @Jaap):
input[, .SD[time, on = "DATE"], by = ID]
объединяет для каждого идентификатора таблицу данных времени с оставшимися столбцами, расширяя таблицу данных.
Затем расширенная версия mevs (dcast(mevs, DATE ~ INDEX_NAME))
присоединяется к расширенной таблице data.table.
Наконец, пропущенные значения в расширенной таблице data.table заполняются функцией na.locf
из пакета zoo
.
Предполагаемый результат будет:
ID T1 T2 T3 DATE GDP CPI
1: ACC001 1 0 0 31/12/2016 1.05 0.02
2: ACC001 1 0 1 30/06/2017 1.06 0.00
3: ACC001 1 0 1 31/12/2017 1.07 -0.01
4: ACC001 1 0 1 30/06/2018 1.08 0.01
5: ACC002 0 1 1 31/12/2016 1.05 0.02
6: ACC002 0 0 0 30/06/2017 1.06 0.00
7: ACC002 0 0 0 31/12/2017 1.07 -0.01
8: ACC002 0 0 0 30/06/2018 1.08 0.01
Но вместо этого я получаю:
ID T1 T2 T3 DATE GDP CPI
1: ACC001 NA NA NA 31/12/2017 1.07 -0.01
2: ACC001 NA NA NA 30/06/2018 1.08 0.01
3: ACC002 NA NA NA 31/12/2017 1.07 -0.01
4: ACC002 NA NA NA 30/06/2018 1.08 0.01
Я почти уверен, что на первом этапе это должен быть неправильный выбор соединения между input
и time
, но я не могу найти обходной путь для этого.
Спасибо всем за ваше время.