【问题标题】:Calculating the date from a series of consecutive time data (R)从一系列连续的时间数据中计算日期 (R)
【发布时间】:2021-03-13 15:21:43
【问题描述】:

我有一列连续时间(小时、分钟、秒),其间隔不等,跨越数天。

例如:

library(lubridate)    
df <- data.frame(Data  = c(1:10),
                     Time = hms(c("10:00:00","15:38:44","22:12:37",
                                  "23:59:00","00:07:28","04:56:00",
                                  "08:01:25","12:10:54","16:08:43",
                                  "20:44:44")))

我想创建一个包含组合日期和时间的新列,假设第一个数据点是在 2020 年 1 月 1 日 10:00:00 获取的。因此,例如,数据点 8 将获得“02.01.2020 12:10:54”。

我解决这个问题的尝试不值得在这里发布,有人有什么建议吗?

非常感谢!

【问题讨论】:

  • #add date: df$date

标签: r date time-series lubridate


【解决方案1】:

这有点棘手,但这里有一个解决方案:

require(tidyverse)    
require(lubridate)

dataf <- tibble(Data  = c(1:16),
                 Time = hms(c("10:00:00","15:38:44","22:12:37",
                              "23:59:00","00:07:28","04:56:00",
                              "08:01:25","12:10:54","16:08:43",
                              "20:44:44","00:07:28","04:56:00",
                              "08:01:25","12:10:54","16:08:43",
                              "20:44:44")))

dataf_2 <- dataf %>% 
  mutate(Data = Data + 1,
         Time_n = as.numeric(Time)) %>% 
  select(Data, Time_n)

dataf %>%
  left_join(dataf_2, by = c("Data")) %>%
  replace_na(list(Time_n = 0)) %>% 
  mutate(starting_date = dmy("01/01/2020")) %>% 
  mutate(change_day = if_else(as.numeric(Time) >= Time_n, 0, 1)) %>% 
  arrange(Data) %>% 
  mutate(cumsum=cumsum(change_day),
         t = paste(hour(Time), minute(Time), second(Time))) %>% 
  mutate(final_date = ymd_hms(paste(starting_date + days(cumsum), t))) %>% 
  select(Data, Time, final_date)

它会产生这样的输出:

# A tibble: 16 x 3
    Data Time        final_date         
   <dbl> <Period>    <dttm>             
 1     1 10H 0M 0S   2020-01-01 10:00:00
 2     2 15H 38M 44S 2020-01-01 15:38:44
 3     3 22H 12M 37S 2020-01-01 22:12:37
 4     4 23H 59M 0S  2020-01-01 23:59:00
 5     5 7M 28S      2020-01-02 00:07:28
 6     6 4H 56M 0S   2020-01-02 04:56:00
 7     7 8H 1M 25S   2020-01-02 08:01:25
 8     8 12H 10M 54S 2020-01-02 12:10:54
 9     9 16H 8M 43S  2020-01-02 16:08:43
10    10 20H 44M 44S 2020-01-02 20:44:44

【讨论】:

  • 非常感谢,这很有前途!它几乎可以工作,但在有两个或多个相同时间的情况下会失败。是否可以使用您的解决方案解决这个问题?示例:dataf &lt;- tibble(Data = c(1:16), Time = hms(c("10:00:00","15:38:44","22:12:37", "23:59:00","00:07:28","04:56:00", "08:01:25","12:10:54","16:08:43", "20:44:44","00:07:28","04:56:00", "04:56:00","12:10:54","16:08:43", "20:44:44")))
  • 你是对的。只需将 if_else(as.numeric(Time) > Time_n, 0, 1) 替换为 if_else(as.numeric(Time) >= Time_n, 0, 1)。我编辑答案
【解决方案2】:

这应该可行:

df %>% 
  mutate(
    lag = lag(Time),
    diff = Time - lag,
    add_days = if_else(is.na(diff), 0, if_else(diff < 0, 1, 0)),
    add_days_cum = cumsum(add_days),
    date = ymd("2020-01-01") + days(add_days_cum) + Time
  )

【讨论】:

  • 感谢您的帮助!不幸的是,我在运行您的代码时收到以下错误消息:“初始化错误(值,...):尝试从不是 S4 对象的对象(类“时期”)获取插槽“年份””
  • 这看起来很奇怪。使用您给定的示例数据集,它适用于 R 4.0.3 和 lubridate 1.7.9.2。请确保没有加载其他包,以免名称冲突。
  • 我使用 RStudio Cloud 测试了这个解决方案,它运行良好 - 非常优雅,谢谢。看来我的 R 安装有问题。
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 2014-12-07
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 2014-02-09
相关资源
最近更新 更多