Запаздывающие данные в зависимости от состояния (нефиксированная задержка) - PullRequest
3 голосов
/ 15 мая 2019

У меня есть данные, упорядоченные в хронологическом порядке возрастания. Это валютные пары, связанные с ценами. Мне нужно создать новый столбец "MtM", который будет равен цене, когда валютная пара XAU / USD. Однако, когда валютная пара отличается от XAU / USD, тогда MtM должен быть равен последней предыдущей цене, в которой валютная пара была равна XAU / USD.

Я пытался отстать, cusum, mutate, но я могу решить только тот случай, когда есть только одно наблюдение, в котором валюта отличается от XAU / USD. Если есть несколько последовательных строк, когда валюта отличается от XAU / USD, я не могу решить.

Currency <- c("XAU/USD", "XAU/USD", "XAU/GBP","XAU/USD","XAU/EUR","XAU/GBP","XAU/USD")
Price <- c(1297, 1296, 1007, 1295, 1005,1004,1298)
df <- data.frame(Currency, Price)

Мне нужно получить

MtM <- c(1297, 1296, 1296, 1295, 1295,1295,1298)
df <- data.frame(Currency, Price, MtM)

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Опция с case_when

library(dplyr)
df %>% 
  mutate(MtM = case_when(Currency == "XAU/USD" ~ Price, TRUE ~ NA_real_)) %>% 
  fill(MtM)
#  Currency Price  MtM
#1  XAU/USD  1297 1297
#2  XAU/USD  1296 1296
#3  XAU/GBP  1007 1296
#4  XAU/USD  1295 1295
#5  XAU/EUR  1005 1295
#6  XAU/GBP  1004 1295
#7  XAU/USD  1298 1298
2 голосов
/ 15 мая 2019

Вот способ использования dplyr и tidyr -

df %>% 
  mutate(
    MtM = ifelse(Currency == "XAU/USD", Price, NA_real_)
  ) %>% 
  fill(MtM)

  Currency Price  MtM
1  XAU/USD  1297 1297
2  XAU/USD  1296 1296
3  XAU/GBP  1007 1296
4  XAU/USD  1295 1295
5  XAU/EUR  1005 1295
6  XAU/GBP  1004 1295
7  XAU/USD  1298 1298
0 голосов
/ 21 мая 2019

Для полноты картины, здесь также есть решение data.table, в котором используется функция nafill() (для новой версии версия разработки 1.12.3 data.table:

library(data.table) # version 1.12.3+
setDT(df)[Currency == "XAU/USD", MtM := Price][, MtM := nafill(MtM, "locf")]
df
   Currency Price  MtM
1:  XAU/USD  1297 1297
2:  XAU/USD  1296 1296
3:  XAU/GBP  1007 1296
4:  XAU/USD  1295 1295
5:  XAU/EUR  1005 1295
6:  XAU/GBP  1004 1295
7:  XAU/USD  1298 1298

Оператор := указывает для обновления по ссылке , т.е. без копирования всего объекта. Это может быть преимуществом в скорости для больших наборов данных.

Для data.table до до версии 1.12.3, na.locf() из пакета zoo можно использовать:

library(data.table)
setDT(df)[Currency == "XAU/USD", MtM := Price][, MtM := zoo::na.locf(MtM, na.rm = FALSE)]
...