【问题标题】:R dplyr: row-based conditions split/apply/combineR dplyr:基于行的条件拆分/应用/组合
【发布时间】:2018-10-28 19:56:14
【问题描述】:

这是this question的dplyr版本

我有以下data.table

initial.date <- as.POSIXct('2018-10-27 10:00:00',tz='GMT')
last.date <- as.POSIXct('2018-10-28 17:00:00',tz='GMT') 
    PriorityDateTime=seq.POSIXt(from=initial.date,to = last.date,by = '30 sec')
    TradePrice=seq(from=1, to=length(PriorityDateTime),by = 1)
    ndf<- data.frame(PriorityDateTime,TradePrice)
    ndf$InstrumentSymbol <- rep_len(x = c('asset1','asset2'),length.out = length(ndf$PriorityDateTime))
    ndf$id <- seq(1:length(x = ndf$InstrumentSymbol))
    ndf$datetime <- ymd_hms(ndf$PriorityDateTime)
    res <- ndf %>% data.table()

看起来像这样:

    > res
         PriorityDateTime TradePrice InstrumentSymbol   id            datetime
   1: 2018-10-27 10:00:00          1           asset1    1 2018-10-27 10:00:00
   2: 2018-10-27 10:00:30          2           asset2    2 2018-10-27 10:00:30
   3: 2018-10-27 10:01:00          3           asset1    3 2018-10-27 10:01:00
   4: 2018-10-27 10:01:30          4           asset2    4 2018-10-27 10:01:30
   5: 2018-10-27 10:02:00          5           asset1    5 2018-10-27 10:02:00

使用dplyr 最优雅、最快捷的方式是:

  1. 拆分:对于每一行定义在过去或未来最多 60 秒(时差小于 60 秒)具有 datetime 的其他行,并且具有相同的 InstrumentSymbol 为这条线的。
  2. 应用:在这些接近的行中,哪一个具有最接近该行的TradePrice[i]TradePrice:获取原始data.frame 中的index 和另一行的TradePrice
  3. 组合:将结果作为新列重新组合到原始 data.table 中,例如作为新列 index.minpricewithin60minpricewithin60

示例结果:

> res
         PriorityDateTime TradePrice InstrumentSymbol   id            datetime minpricewithin60 index.minpricewithin60
   1: 2018-10-27 10:00:00          1           asset1    1 2018-10-27 10:00:00                2                      2
   2: 2018-10-27 10:00:30          2           asset2    2 2018-10-27 10:00:30                4                      4
   3: 2018-10-27 10:01:00          3           asset1    3 2018-10-27 10:01:00                1                      1
   4: 2018-10-27 10:01:30          4           asset2    4 2018-10-27 10:01:30                2                      2
   5: 2018-10-27 10:02:00          5           asset1    5 2018-10-27 10:02:00                3                      3

我想我的问题可以被问为“如何以与apply(df,1, function(x) df$column-x["column"]) 类似的方式修复dplyr 中的一行 我有使用dplyr 的潜在解决方案,但到目前为止一切都很慢。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    使用dplyr包和lapply函数的解决方案:

    result_df <- do.call(rbind, lapply(1:nrow(res), function(row_id) {
    
                 temp <-   res %>% filter(InstrumentSymbol == res$InstrumentSymbol[row_id]) %>% 
                           mutate(time_diff = abs(difftime(res$datetime[row_id], datetime, units = "secs")),
                                  diff_price = abs(TradePrice - res$TradePrice[row_id])) %>% 
                           filter(id != res$id[row_id], time_diff <= 60) %>% 
                           filter(diff_price == min(diff_price)) %>% select(TradePrice, id) %>% 
                           rename(minpricewithin60 = TradePrice, index.minpricewithin60 = id)
    
                 if(nrow(temp) == 0) temp[1,] <- c(NA, NA)
    
                 return(bind_cols(res %>% slice(rep(row_id, nrow(temp))), temp))
                                                                      }))
    
    head(result_df)
    
         PriorityDateTime TradePrice InstrumentSymbol id            datetime minpricewithin60 index.minpricewithin60
    1 2018-10-27 10:00:00          1           asset1  1 2018-10-27 10:00:00                3                      3
    2 2018-10-27 10:00:30          2           asset2  2 2018-10-27 10:00:30                4                      4
    3 2018-10-27 10:01:00          3           asset1  3 2018-10-27 10:01:00                1                      1
    4 2018-10-27 10:01:00          3           asset1  3 2018-10-27 10:01:00                5                      5
    5 2018-10-27 10:01:30          4           asset2  4 2018-10-27 10:01:30                2                      2
    6 2018-10-27 10:01:30          4           asset2  4 2018-10-27 10:01:30                6                      6
    

    【讨论】:

    • 谢谢,但是这很慢,有更快的方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多