Я думаю, что ваше намерение слиться / присоединиться - правильный путь к go. На самом деле, это «правильно», потому что естественно будет лучше справляться с аномалиями данных. Я также думаю, что в вашем коде есть пара небольших ошибок logi c.
Поскольку вашим данным недостаточно для просмотра прошлых лет, вот некоторые поддельные данные. Я делаю SPOT
просто последовательность, чтобы помочь визуализировать последовательность, но в остальном это не имеет большого значения. Я также собираюсь представить две аномалии в данных, чтобы продемонстрировать, как они будут отображаться в конце.
library(dplyr)
library(lubridate)
dates <- seq.Date(as.Date("2020-03-15"), by = "day", length.out = 5)
df <- tibble(
iso = rep(c("AUD", "USD"), each = 10),
date = rep(c(dates - years(1), dates), times = 2),
SPOT = 1:20
)
# data missingness
df <- df[-3,]
# repeated date
df$date[12] <- df$date[13]
df
# # A tibble: 19 x 3
# iso date SPOT
# <chr> <date> <int>
# 1 AUD 2019-03-15 1
# 2 AUD 2019-03-16 2
# 3 AUD 2019-03-18 4
# 4 AUD 2019-03-19 5
# 5 AUD 2020-03-15 6
# 6 AUD 2020-03-16 7
# 7 AUD 2020-03-17 8
# 8 AUD 2020-03-18 9
# 9 AUD 2020-03-19 10
# 10 USD 2019-03-15 11
# 11 USD 2019-03-16 12
# 12 USD 2019-03-18 13
# 13 USD 2019-03-18 14
# 14 USD 2019-03-19 15
# 15 USD 2020-03-15 16
# 16 USD 2020-03-16 17
# 17 USD 2020-03-17 18
# 18 USD 2020-03-18 19
# 19 USD 2020-03-19 20
Используя ваш код сверху, мы видим это:
df %>%
mutate(date = date - years(1)) %>%
rename(LAG1_SPOT = SPOT) %>%
right_join(., df, by = c("iso", "date"))
# # A tibble: 19 x 4
# iso date LAG1_SPOT SPOT
# <chr> <date> <int> <int>
# 1 AUD 2019-03-15 6 1
# 2 AUD 2019-03-16 7 2
# 3 AUD 2019-03-18 9 4
# 4 AUD 2019-03-19 10 5
# 5 AUD 2020-03-15 NA 6
# 6 AUD 2020-03-16 NA 7
# 7 AUD 2020-03-17 NA 8
# 8 AUD 2020-03-18 NA 9
# 9 AUD 2020-03-19 NA 10
# 10 USD 2019-03-15 16 11
# 11 USD 2019-03-16 17 12
# 12 USD 2019-03-18 19 13
# 13 USD 2019-03-18 19 14
# 14 USD 2019-03-19 20 15
# 15 USD 2020-03-15 NA 16
# 16 USD 2020-03-16 NA 17
# 17 USD 2020-03-17 NA 18
# 18 USD 2020-03-18 NA 19
# 19 USD 2020-03-19 NA 20
Поскольку я полагаю, что вы намерены сравнить данные за этот год с данными за прошлый год, то вышеизложенное показывает, что мы их сопоставили, но дата ссылки - прошлогодняя. Я предлагаю вам использовать +
:
df %>%
mutate(date = date + years(1)) %>%
rename(LAG1_SPOT = SPOT) %>%
right_join(., df, by = c("iso", "date"))
# # A tibble: 20 x 4
# iso date LAG1_SPOT SPOT
# <chr> <date> <int> <int>
# 1 AUD 2019-03-15 NA 1
# 2 AUD 2019-03-16 NA 2
# 3 AUD 2019-03-18 NA 4
# 4 AUD 2019-03-19 NA 5
# 5 AUD 2020-03-15 1 6
# 6 AUD 2020-03-16 2 7
# 7 AUD 2020-03-17 NA 8
# 8 AUD 2020-03-18 4 9
# 9 AUD 2020-03-19 5 10
# 10 USD 2019-03-15 NA 11
# 11 USD 2019-03-16 NA 12
# 12 USD 2019-03-18 NA 13
# 13 USD 2019-03-18 NA 14
# 14 USD 2019-03-19 NA 15
# 15 USD 2020-03-15 11 16
# 16 USD 2020-03-16 12 17
# 17 USD 2020-03-17 NA 18
# 18 USD 2020-03-18 13 19
# 19 USD 2020-03-18 14 19
# 20 USD 2020-03-19 15 20
Это также показывает, как будут отображаться аномалии данных. Во-первых, в AUD
мы видим, что в 03-17
отсутствуют данные за прошлый год, поэтому нам не с чем сравнить спот 8
с. Это просто тот факт, что нам не хватает данных. Это неизбежно, но lag
здесь даст нам данные, вероятно, с неправильной даты. Во-вторых, мы видим, что наши двойные данные (системы сбора данных несовершенны!), Теперь у нас есть две строки для USD
на 2020-03-18
, что, безусловно, подозрительно (но выходит за рамки вашего вопроса). Но мы сравнили оба значения 2019 года с одним значением 2020 года.
Если аномалии данных никогда не появляются в ваших данных, я все еще думаю, что join
является правильным методом для решения этой проблемы, как будто есть когда lag
найдет неправильную строку (високосные годы?), вы никогда не узнаете, что она не удалась: вы получите данные и будете использовать их без указания.
Кстати: если вы просто уменьшая четыре строки кода, это совершенно эквивалентно:
transmute(df, iso, date = date + years(1), LAG1_SPOT = SPOT) %>%
right_join(., df, by = c("iso", "date"))