提问人:Minh Chau 提问时间:11/11/2023 最后编辑:benson23Minh Chau 更新时间:11/11/2023 访问量:56
R 计算午夜后的小时数
R calculate hours after midnight
问:
我想使用 R 来计算 R 中两个军事时间(例如,13:00 和 7:00)之间的时差。
编号 | 开始时间 | 结束时间 |
---|---|---|
1 | 18:00 | 2:00 |
2 | 18:00 | 20:00 |
3 | 2:00 | 4:00 |
我想计算 start.time 和 end.time 之间的时间差。我希望我的结果如下:
编号 | 开始时间 | 结束时间 | 差异 |
---|---|---|---|
1 | 18:00 | 2:00 | 8 |
2 | 18:00 | 20:00 | 2 |
3 | 2:00 | 4:00 | 2 |
如。POSIXct(
) 和 difftime()
我尝试使用并将 start.time 和 end.time 转换为 datetime 类,并用于查找它们之间的时间差。这仅适用于 2 和 3。对于第一个,参数将所有时间都变成同一个日期,因此它们之间的差值不等于 8。as.posixct(start.time, format = '%H:%M')
as.POSIXct(end.time, format = '%H:%M')
difftime()
as.POSIXct()
我的问题是:有没有可以考虑所有这些场景的代码?
答:
以下代码将实现您正在寻找的内容,尽管它可能难以概括。
data<-data.frame(
id=c(1,2,3),
start.time=c("18:00","18:00","2:00"),
end.time=c("2:00","20:00","4:00")
)
library(tidyverse)
data<-mutate(data,
start.time=as.numeric(gsub("\\:.*","",start.time)),
end.time=as.numeric(gsub("\\:.*","",end.time)),
diff=ifelse(end.time>start.time,end.time-start.time,
(24-start.time)+end.time))
你只需从 if 中减去 if 更大。如果较大,则先从 24 中减去,然后添加 。这取决于分钟数无关紧要,因为我过去常常删除 .end.time
start.time
end.time
start.time
start.time
end.time
gsub()
:
您可以先将小时数转换为 R POSIXct 对象,然后添加一天(如果它早于 )。最后用于计算它们的小时差并删除任何不需要的列(最终函数)。end.time
start.time
difftime
select
library(dplyr)
df %>% mutate(across(ends_with("time"), ~as.POSIXct(.x, format = '%H:%M'), .names = "{.col}2"),
end.time2 = if_else(end.time2 < start.time2, end.time2 + 1*60*60*24, end.time2),
difftime = difftime(end.time2, start.time2)) %>%
select(-ends_with("2"))
id start.time end.time difftime
1 1 18:00 2:00 8 hours
2 2 18:00 20:00 2 hours
3 3 2:00 4:00 2 hours
评论
您可以将 24*60^2 秒(一天)添加到行差异小于零的日期时间。由于结果是秒,我们将其除以 。 这里会快如闪电。60^2
matrixStats::rowDiffs
> transform(dat,
+ diff=sapply(dat[2:3], as.POSIXct, format='%H:%M') |>
+ {\(.) {
+ nw_dy <- matrixStats::rowDiffs(.) < 0
+ .[nw_dy, 2] <- .[nw_dy, 2] + 24*60^2
+ unname(.)
+ }}() |>
+ matrixStats::rowDiffs()/60^2)
id start.time end.time diff
1 1 18:00 2:00 8
2 2 18:00 20:00 2
3 3 2:00 4:00 2
如果没有 matrixStats,您可以执行以下操作,当然,这会更慢:
> transform(dat,
+ diff=sapply(dat[2:3], as.POSIXct, format='%H:%M') |>
+ {\(.) {
+ nw_dy <- .[, 'end.time'] - .[, 'start.time'] < 0
+ .[nw_dy, 2] <- .[nw_dy, 2] + 24*60^2
+ unname(.)
+ }}() |>
+ apply(1, diff)/60^2)
id start.time end.time diff
1 1 18:00 2:00 8
2 2 18:00 20:00 2
3 3 2:00 4:00 2
数据:
> dput(dat)
structure(list(id = 1:3, start.time = c("18:00", "18:00", "2:00"
), end.time = c("2:00", "20:00", "4:00")), class = "data.frame", row.names = c(NA,
-3L))
评论