R 基于条件的滞后数据(非固定滞后)

R 基于条件的滞后数据(非固定滞后),r,conditional-statements,lag,R,Conditional Statements,Lag,我将数据按时间升序排列。这些是与价格相关联的货币对。我需要创建一个新的“MtM”列,该列将等于货币对为XAU/USD时的价格。但是,当货币对与XAU/USD不同时,MtM需要等于货币对等于XAU/USD的上一个价格 我曾尝试过滞后、cusum、变异,但我只能解决只有一个观察结果表明货币与XAU/USD不同的情况。如果货币与XAU/USD不同时有多个连续行,我无法解决 Currency <- c("XAU/USD", "XAU/USD", "XAU/GBP","XAU/USD","XAU/E

我将数据按时间升序排列。这些是与价格相关联的货币对。我需要创建一个新的“MtM”列,该列将等于货币对为XAU/USD时的价格。但是,当货币对与XAU/USD不同时,MtM需要等于货币对等于XAU/USD的上一个价格

我曾尝试过滞后、cusum、变异,但我只能解决只有一个观察结果表明货币与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)

Currency这里有一种使用
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

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

为了完整起见,这里还有一个
data.table
解决方案,它使用
nafill()
函数(新增了:

:=
操作符指示通过引用进行更新,即不复制整个对象。这对于大型数据集来说是一个速度优势

对于1.12.3版之前的
data.table
,可以使用
zoo
软件包中的
na.locf()

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

最后一行可以写入
setDT(df)[Currency==“XAU/USD”,MtM:=Price][,MtM:=zoo::na.locf0(MtM)]
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
library(data.table)
setDT(df)[Currency == "XAU/USD", MtM := Price][, MtM := zoo::na.locf(MtM, na.rm = FALSE)]