【问题标题】:How to transfer milliseconds from POSIXct to another POSIXct based on a third column in r如何基于 r 中的第三列将毫秒从 POSIXct 转移到另一个 POSIXct
【发布时间】:2019-11-17 06:29:32
【问题描述】:

我每天有大约 50 个独特的事件发生不止一次。解决方案应该通过事件检查它们的开始时间是否在timestamp 列中引用它们。由于timestamp 存储,startend 时间。并且,有些事件可能一个接一个地发生,具有不同的开始时间和不同的结束时间。

我很难弄清楚以下几点:

我有一个小标题:
timestamp 包含精确到毫秒的事件的确切开始和结束,所以startstop 都在timestamp start 列包含事件的开始,不包括毫秒
stop 列包含事件的结束,精确到毫秒 event 列包含事件的名称

我想将事件开始时的timestamp 的毫秒数转移到start 列中的start 列中开始的特定事件的毫秒数。

   options(digits.secs=3)
   timestamp <- as.POSIXct(c("2019-01-07 06:05:23.582 CET", "2019-01-07 06:05:23.582 CET", "2019-01-07 06:05:23.582 CET",
               "2019-01-07 06:05:43.967 CET", "2019-01-07 06:05:43.967 CET", "2019-01-07 06:05:43.967 CET",
               "2019-01-07 06:05:45.026 CET","2019-01-07 06:07:10.463 CET", "2019-01-07 06:07:10.463 CET",
               "2019-01-07 06:07:18.467 CET"))

   start <- as.POSIXct(c("2019-01-07 06:05:23 CET", "2019-01-07 06:05:23 CET", "2019-01-07 06:05:23 CET", "2019-01-07 06:05:23 CET",
          "2019-01-07 06:05:23 CET", "2019-01-07 06:05:23 CET", "2019-01-07 06:05:23 CET", "2019-01-07 06:07:10 CET",
          "2019-01-07 06:07:10 CET", "2019-01-07 06:07:10 CET"))

   stop <- as.POSIXct(c(NA, NA, NA, "2019-01-07 06:05:43.967 CET", NA, "2019-01-07 06:05:43.967 CET",
         "2019-01-07 06:05:45.026 CET", NA, NA, "2019-01-07 06:07:18.467 CET"))

   event <- c("A",    "A",  "B", "A",   "B", "A",   "B", "C", "B", "B")

   df <- tibble(timestamp = timestamp, start = start, stop = stop, event = event)
   df

最终目标如下表:

      start                    stop                    event
      <dttm>                   <dttm>                  <chr>
    1 2019-01-07 06:05:23.582  2019-01-07 06:05:43.967  A    
    2 2019-01-07 06:05:23.582  2019-01-07 06:05:45.026  B    
    3 2019-01-07 06:07:10.463  2019-01-07 06:07:18.467  B 

timestamp 转移到start 列的事件开始的毫秒数。 在我的例子中,事件 A 发生了两次,开始和停止时间完全相同,精确到毫秒,所以只需要一个事件。

提前谢谢你!

【问题讨论】:

    标签: r for-loop dplyr tidyverse lubridate


    【解决方案1】:

    我确信这可以改进,但似乎可以满足您的要求:

    library(lubridate); library(dplyr)
    df %>%
      # Add to the original table...
      inner_join(
        # based on a lookup table connecting the rounded starts with "real start"
        df %>% 
          mutate(real_start = if_else(timestamp %>% floor_date("seconds") == start,
                              timestamp, ymd_h(NA_real_))) %>%
          select(start, real_start) %>%
          tidyr::drop_na()
      ) %>%
      tidyr::drop_na() %>%
      distinct(event, real_start, stop)
    
    # A tibble: 3 x 3
      event real_start              stop                   
      <chr> <dttm>                  <dttm>                 
    1 A     2019-01-07 06:05:23.582 2019-01-07 06:05:43.967
    2 B     2019-01-07 06:05:23.582 2019-01-07 06:05:45.026
    3 B     2019-01-07 06:07:10.463 2019-01-07 06:07:18.467
    

    【讨论】:

    • 不幸的是,此解决方案不会检查事件的开始时间是否在 timestamp 列中引用它们。由于时间戳存储,两者都开始结束时间。
    • 不确定我是否理解。 real_start = if_else(timestamp %&gt;% floor_date("seconds") == start, 检查时间戳的截断版本是否与start 匹配,如果匹配,则使用更精确的数字。然后将其连接到原始内容,因此我们看到 real_start 列使用时间戳编号,并且似乎与您想要的输出相匹配。
    • 是的,很抱歉,我一整天都在试图弄清楚。您的解决方案是正确的。问题不在于您的方法,而在于数据的存储方式 - 因此timestamp 列恰好不是startstop 的参考列,除此之外,某些事件没有start 时间或 stop 时间。当我试图进行回查时 - 我对结果感到困惑。最初,我认为问题出在方法上,但是,不,不是。无论如何,我很抱歉,谢谢你的回复。 -一切顺利
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 2013-05-09
    相关资源
    最近更新 更多