【问题标题】:R - tagging rows based on time intervalsR - 基于时间间隔标记行
【发布时间】:2021-07-15 19:04:31
【问题描述】:

我正在处理一些销售数据,我需要根据交易发生的事件标记每笔交易。我有 2 个 dfs:

带有向量日期时间的 df1,其中包含交易第二个的 POSIXct 日期时间以及其他未触及的交易数据

datetime transaction.id
"2015-09-10 21:03:15 CDT" "123abc"
"2015-09-12 20:59:13 CDT" "345bcd"

df2 包含三个向量,event.name、start.time 和 interval(润滑间隔 +- start.time 的 2 小时,表示商店开张的时间)。

event.name start.time interval
"Event 1" "2015-09-10 20:00:00 CDT" 2015-09-10 18:00:00 CDT--2015-09-10 22:00:00 CDT
"Event 2" "2015-09-12 20:00:00 CDT" 2015-09-12 18:00:00 CDT--2015-09-12 22:00:00 CDT

我尝试过使用 dplyr mutate:

df1 %>% mutate(event.name = ifelse(datetime %within% df2$interval, df2$event.name, NA))

但它想应用整个向量。

我也尝试过使用左连接,但它不接受 by = 参数的逻辑

left_join(df1, df2, by = (df1$datetime %within% df2$interval))

关于如何将正确的事件标签应用于每笔交易的任何想法?

预期输出:

datetime transaction.id event.name
"2015-09-10 21:03:15 CDT" "123abc" "Event 1"
"2015-09-12 20:59:13 CDT" "345bcd" "Event 2"

编辑: 感谢所有为此提供帮助的人 - 我发现最好的方法是使用 while 循环来处理事件。

y <- 1

while (y < 1000)
{ x <- df2$event.name[y]
interval <- df2$interval[y]
temp2 <- df1$datetime %within% interval 
df1 <- df1 %>%
  mutate (temp = temp2)
df1 <- df1 %>%
  mutate (event.name = if_else(temp==TRUE, x, df2$event.name))
y = y + 1
}

这很粗糙,但这样做可以让它大规模运行,同时避免混淆“接近”匹配(我的数据集有 1000 个事件和 500k+ 事务。希望这对其他人有帮助!

【问题讨论】:

  • 请展示一个带有dput 和预期输出的可重现的小例子

标签: r


【解决方案1】:

这个 data.table 解决方案让你接近。

library(data.table)
library(stringr)
x <- data.table(
  datetime = as.POSIXct(
    c(
  "2015-09-10 21:03:15 CDT",
  "2015-09-12 20:59:13 CDT")
  ),
  transaction.id = 
    c("123abc", "345bcd"))
x[, start.time := datetime]
setkey(x, start.time)
y <- data.table(
  event.name = c("Event 1", "Event 2"),
  start.time = as.POSIXct(c(
    "2015-09-10 20:00:00 CDT", "2015-09-12 20:00:00 CDT"
  )),
  interval = c(
    "2015-09-10 18:00:00 CDT--2015-09-10 22:00:00 CDT",
    "2015-09-12 18:00:00 CDT--2015-09-12 22:00:00 CDT"
  )
)
y[, `:=`(
  start = as.POSIXct(str_remove(interval, "\\-{2}.*$")),
  end = as.POSIXct(str_remove(interval, "^.*\\-{2}")))][, 
  interval := NULL]
setkey(y, start, end)
x[y, roll = "nearest"]

【讨论】:

    【解决方案2】:

    您可能想试试fuzzyjoin 包。您可以将 fuzzy_left_join 与两个数据框一起使用,使用间隔中的开始和结束日期时间。

    library(fuzzyjoin)
    library(lubridate)
    
    df2$start <- int_start(df2$interval)
    df2$end <- int_end(df2$interval)
    
    fuzzy_left_join(
      df1,
      df2,
      by = c("datetime" = "start", "datetime" = "end"),
      match_fun = c(`>=`, `<=`)
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-06
      • 2012-12-23
      • 2020-03-12
      • 1970-01-01
      相关资源
      最近更新 更多