【问题标题】:How to calculate hours between two as.characters with the format "dd-mm-yyyy hh:mm"如何计算两个 as.characters 之间的小时数,格式为“dd-mm-yyyy hh:mm”
【发布时间】:2021-05-01 18:12:00
【问题描述】:

我有utime1time2 都以dd-mm-yyyy hh:mm 的格式列出。我想生成一个新的协变量,其中包含 u$time1u$time2 之间的 hours

他们被列为as.character

str(u)
'data.frame':   5765 obs. of  2 variables:
 $ time1: chr  "30-01-2020 07:20" "25-04-2019 15:05" "11-01-2019 22:01" "11-01-2019 22:01" ...
 $ time2: chr  "14-02-2020 15:34" "27-04-2019 10:56" "12-01-2019 00:42" "23-01-2019 10:08" ...

预期输出

>  head(u)
             time1            time2                            new
1 30-01-2020 07:20 14-02-2020 15:34  hours between time1 and time2
2 25-04-2019 15:05 27-04-2019 10:56  hours between time1 and time2
3 11-01-2019 22:01 12-01-2019 00:42  hours between time1 and time2
4 11-01-2019 22:01 23-01-2019 10:08  hours between time1 and time2

如果小时数有一个小数点,我会更喜欢,并且最好使用dplyrlubridate 的解决方案。

u <- structure(list(time1 = c("30-01-2020 07:20", "25-04-2019 15:05", 
"11-01-2019 22:01", "11-01-2019 22:01", "17-04-2018 07:55"), 
    time2 = c("14-02-2020 15:34", "27-04-2019 10:56", "12-01-2019 00:42", 
    "23-01-2019 10:08", "20-04-2018 11:04")), row.names = c(NA, 
5L), class = "data.frame")

【问题讨论】:

  • “一个小数点” 是一个数据丢失操作。我建议您在呈现为报告之前的最后一步中这样做,而不是在处理的早期。为此,它是round(.,0)(仍然是一个数字)或sprintf("%0.1f",.)(现在是一个字符串,此字段不再有数学)之一。

标签: r dataframe time dplyr lubridate


【解决方案1】:

这是一个使用data.table的非常快速的解决方案

library(data.table)
library(lubridate)


setDT(u)
u[, time1 := dmy_hm(time1)]
u[, time2 := dmy_hm(time2)]

u[, diff := difftime(time1, time2, units = "hours")]

u
>                  time1               time2              diff
> 1: 2020-01-30 07:20:00 2020-02-14 15:34:00 -368.233333 hours
> 2: 2019-04-25 15:05:00 2019-04-27 10:56:00  -43.850000 hours
> 3: 2019-01-11 22:01:00 2019-01-12 00:42:00   -2.683333 hours
> 4: 2019-01-11 22:01:00 2019-01-23 10:08:00 -276.116667 hours
> 5: 2018-04-17 07:55:00 2018-04-20 11:04:00  -75.150000 hours

【讨论】:

    【解决方案2】:

    转换成POSIXct后可以使用difftime

    with(u, difftime(as.POSIXct(time1, format = '%d-%m-%Y %H:%M'), 
           as.POSIXct(time2, format = '%d-%m-%Y %H:%M'), units = 'hour'))
    

    或者如 cmets 中提到的@r2evans,lubridate 选项是

    library(lubridate)
    as.numeric(dmy_hm(u$time1) - dmy_hm(u$time2), units = "hours")
    

    【讨论】:

    • arg 是 units= 以防有人有 options(warnPartialMatchArgs=TRUE) :-)
    • @r2evans 谢谢,我在记住它是单位还是单位时总是有这个问题
    • 设置选项,您将不会再错过它......直到您厌倦了所有进行部分匹配的软件包。我有warnPartialMatchDollarwarnPartialMatchAttr 设置,但我无法长期使用warnPartialMatchArgs 设置。
    • 因为他们标记了lubridate,另一个选项是as.numeric(dmy_hm(u$time1) - dmy_hm(u$time2), units = "hours")
    • 不,你明白了......无论如何我更喜欢基地:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2015-10-08
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多