【问题标题】:Finding past events in dplyr在 dplyr 中查找过去的事件
【发布时间】:2017-09-27 08:19:46
【问题描述】:

我有一个半周期测量的列表 - 这意味着它们应该在一个间隔内完成,但是有时会有 NA 并且测量将重新开始。

在另一个列表中,我有关于事件的信息。

对于每次测量,我想知道过去最后一次事件的日期。我如何在 R 中做到这一点,最好使用 dplyr?

library(dplyr)
library(lubridate)

measurements <- tibble(timestamp = seq(ymd('2017-01-01'), 
                                       ymd('2017-01-20'), 
                                       by = "2 days"),
                       data = runif(10))

events <- tibble(timestamp = ymd('2017-01-04', '2017-01-12'), 
                 type = 'Start')

expected = ymd(NA, NA, '2017-01-04', '2017-01-04', 
               '2017-01-04', '2017-01-04', 
               '2017-01-12', '2017-01-12',
               '2017-01-12', '2017-01-12')

measurements %>% mutate(distance = expected)

# A tibble: 10 x 3
    timestamp       data   distance
       <date>      <dbl>     <date>

 1 2017-01-01 0.01037106         NA
 2 2017-01-03 0.50183512         NA
 3 2017-01-05 0.80695523 2017-01-04
 4 2017-01-07 0.98605880 2017-01-04
 5 2017-01-09 0.78591144 2017-01-04
 6 2017-01-11 0.02296494 2017-01-04
 7 2017-01-13 0.94335407 2017-01-12
 8 2017-01-15 0.10540759 2017-01-12
 9 2017-01-17 0.27344290 2017-01-12
10 2017-01-19 0.09080328 2017-01-12

【问题讨论】:

  • 不完全确定“最后一个”是什么意思。假设您想要 2017-1-1 的距离为 2017-01-04,那么这将起作用:measurements %&gt;% mutate(distance = expected) -&gt; d; d %&gt;% group_by(distance) %&gt;% summarise(min(timestamp)).
  • 其实expected是OP想要的o/p。条件是measurements$timestamp 必须与events$timestamp 进行比较,并且最近/最后日期必须应用于距离。
  • 我只想计算变量“预期”而不是输入它。
  • 乍一看,这看起来像是一个滚动连接的案例,目前是not supported by dplyr。不过,data.table 应该很简单。

标签: r dplyr tidyverse


【解决方案1】:

一个选项是expand 数据,然后left_join 与其他数据集

library(tidyverse)
events %>% 
    transmute(timestamp, distance = timestamp) %>%
    right_join(., expand( measurements, timestamp = seq(first(timestamp),
                        last(timestamp), by = "day"))) %>%
    fill(distance) %>% 
    left_join(measurements, ., by = 'timestamp')
 # A tibble: 10 x 3
 #   timestamp      data   distance
 #      <date>     <dbl>     <date>
 #1 2017-01-01 0.6299731         NA
 #2 2017-01-03 0.1838285         NA
 #3 2017-01-05 0.8636441 2017-01-04
 #4 2017-01-07 0.7465680 2017-01-04
 #5 2017-01-09 0.6682846 2017-01-04
 #6 2017-01-11 0.6180179 2017-01-04
 #7 2017-01-13 0.3722381 2017-01-12
 #8 2017-01-15 0.5298357 2017-01-12
 #9 2017-01-17 0.8746823 2017-01-12
 #102017-01-19 0.5817501 2017-01-12

或者另一个选项是data.table,通过指定roll

library(data.table)
library(zoo)
setDT(measurements)[as.data.table(events)[, distance := timestamp
    ], distance := distance , on = 'timestamp', roll = -Inf
     ][, distance := na.locf(distance, na.rm = FALSE)]
measurements
#     timestamp      data   distance
# 1: 2017-01-01 0.2387260       <NA>
# 2: 2017-01-03 0.9623589       <NA>
# 3: 2017-01-05 0.6013657 2017-01-04
# 4: 2017-01-07 0.5150297 2017-01-04
# 5: 2017-01-09 0.4025733 2017-01-04
# 6: 2017-01-11 0.8802465 2017-01-04
# 7: 2017-01-13 0.3640919 2017-01-12
# 8: 2017-01-15 0.2882393 2017-01-12
# 9: 2017-01-17 0.1706452 2017-01-12
#10: 2017-01-19 0.1721717 2017-01-12

注意:由于未设置 seed,如果我们再次创建“测量”数据集,“数据”(rnorm) 的值将不同

或者正如@Henrik 提到的,如果我们不想更改“测量”数据集,我们可以这样做

setDT(events)[setDT(measurements), .(timestamp, data, x.timestamp),
             on = "timestamp", roll = Inf]

【讨论】:

  • setDT(events)[setDT(measurements), .(timestamp, data, x.timestamp), on = "timestamp", roll = Inf]
猜你喜欢
  • 2020-06-12
  • 2015-05-15
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多