我的数据按时间升序排列。这些是与价格相关的货币对。我需要创建一个新的“ 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)
答案 0 :(得分:2)
这是使用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
答案 1 :(得分:2)
带有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 :(得分:0)
为了完整起见,这也是一个data.table
解决方案,它使用nafill()
函数(development version 1.12.3 of 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
:=
运算符指示通过引用进行更新,即,不复制整个对象。对于大型数据集,这可能是速度优势。
对于版本{1.12.3之前的data.table
,可以使用na.locf()
软件包中的zoo
:
library(data.table)
setDT(df)[Currency == "XAU/USD", MtM := Price][, MtM := zoo::na.locf(MtM, na.rm = FALSE)]