【问题标题】:Lagging data based on condition (non-fix lag)基于条件的滞后数据(非固定滞后)
【发布时间】:2019-10-02 19:39:37
【问题描述】:

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

我尝试过滞后、累积、变异,但我只能解决只有一个观察到货币与 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)

【问题讨论】:

    标签: r conditional-statements lag


    【解决方案1】:

    这是一种使用dplyrtidyr 的方法-

    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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

        【解决方案3】:

        为了完整起见,这里还有一个使用nafill() 函数的data.table 解决方案(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
        

        := 运算符指示通过引用更新,即不复制整个对象。对于大型数据集,这可能是速度优势。

        对于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)]
        

        【讨论】:

        • 最后一行可以写setDT(df)[Currency == "XAU/USD", MtM := Price][, MtM := zoo::na.locf0(MtM)]
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-08
        • 2020-04-10
        • 1970-01-01
        • 1970-01-01
        • 2016-07-23
        相关资源
        最近更新 更多