计算 R 中两个事件(给定日期和时间)之间的时间差
Calculate time difference between two events (given date and time) in R
我目前正在努力解决一个关于计算两个事件之间的时间差的初学者问题。
我想考虑一个由日期和时间组成的列(一列中的两个值),并计算 previous/next 行的值与 相同 ID(本例中为A或B)。
ID = c("A", "A", "B", "B")
time = c("08.09.2014 10:34","12.09.2014 09:33","13.08.2014 15:52","11.09.2014 02:30")
d = data.frame(ID,time)
我想要的输出格式为 Hours:Minutes
time difference = c("94:59","94:59","682:38","682:38")
格式Days:Hours:Minutes
或任何类似的格式也可以,只要它可以方便地实现。我对输出的格式很灵活,以上只是我的一个想法。
对于每个 ID,我总是有两行(在示例中为 2xA 和 2xB)。我没有一个令人信服的想法如何避免重复差异。
我之前尝试过一些示例,这些示例是我在 Whosebug 上找到的。他们中的大多数人使用 POSIXt
和 strptime
。但是,我没有设法将这些想法应用到我的数据集中。
这是我使用 dplyr
的尝试
library(dplyr)
d %>%
mutate(time = as.POSIXct(time, format = "%d.%m.%Y %H:%M")) %>%
group_by(ID) %>%
mutate(diff = paste0(gsub("[.].*", "", diff(time)*24), ":",
round(as.numeric(gsub(".*[.]", ".", diff(time)*24))*60)))
# Source: local data frame [4 x 3]
# Groups: ID
#
# ID time diff
# 1 A 2014-09-08 10:34:00 94:59
# 2 A 2014-09-12 09:33:00 94:59
# 3 B 2014-08-13 15:52:00 682:38
# 4 B 2014-09-11 02:30:00 682:38
一个非常(对我来说)hack-ish 的基本解决方案:
ID <- c("A", "A", "B", "B")
time <- c("08.09.2014 10:34", "12.09.2014 09:33", "13.08.2014 15:52","11.09.2014 02:30")
d <- data.frame(ID, time)
d$time <- as.POSIXct(d$time, format="%d.%m.%Y %H:%M")
unlist(unname(lapply(split(d, d$ID), function(d) {
sapply(abs(diff(c(d$time[2], d$time))), function(x) {
sprintf("%s:%s", round(((x*24)%/%1)), round(((x*24)%%1 *60)))
})
})))
## [1] "94:59" "94:59" "682:38" "682:38"
我不得不相信这个功能已经存在于某处,不过。
类似于 David 和 hrmbrmstr 的尝试,我发现这个使用 difftime
的解决方案有效
我使用在 Whosebug 上找到的行移位脚本
rowShift <- function(x, shiftLen = 1L) {
r <- (1L + shiftLen):(length(x) + shiftLen)
r[r<1] <- NA
return(x[r])
}
d$time.c <- as.POSIXct(d$time, format = "%d.%m.%Y %H:%M")
d$time.prev <- rowShift(d$time.c,-1)
d$diff <- difftime(d$time.c,d$time.prev, units="hours")
d$diff
的每隔一行在结果中有 positive/negative 个值。我确实删除了所有具有负值的行,并且每个 ID 的第一次和最后一次之间存在差异。
我目前正在努力解决一个关于计算两个事件之间的时间差的初学者问题。
我想考虑一个由日期和时间组成的列(一列中的两个值),并计算 previous/next 行的值与 相同 ID(本例中为A或B)。
ID = c("A", "A", "B", "B")
time = c("08.09.2014 10:34","12.09.2014 09:33","13.08.2014 15:52","11.09.2014 02:30")
d = data.frame(ID,time)
我想要的输出格式为 Hours:Minutes
time difference = c("94:59","94:59","682:38","682:38")
格式Days:Hours:Minutes
或任何类似的格式也可以,只要它可以方便地实现。我对输出的格式很灵活,以上只是我的一个想法。
对于每个 ID,我总是有两行(在示例中为 2xA 和 2xB)。我没有一个令人信服的想法如何避免重复差异。
我之前尝试过一些示例,这些示例是我在 Whosebug 上找到的。他们中的大多数人使用 POSIXt
和 strptime
。但是,我没有设法将这些想法应用到我的数据集中。
这是我使用 dplyr
library(dplyr)
d %>%
mutate(time = as.POSIXct(time, format = "%d.%m.%Y %H:%M")) %>%
group_by(ID) %>%
mutate(diff = paste0(gsub("[.].*", "", diff(time)*24), ":",
round(as.numeric(gsub(".*[.]", ".", diff(time)*24))*60)))
# Source: local data frame [4 x 3]
# Groups: ID
#
# ID time diff
# 1 A 2014-09-08 10:34:00 94:59
# 2 A 2014-09-12 09:33:00 94:59
# 3 B 2014-08-13 15:52:00 682:38
# 4 B 2014-09-11 02:30:00 682:38
一个非常(对我来说)hack-ish 的基本解决方案:
ID <- c("A", "A", "B", "B")
time <- c("08.09.2014 10:34", "12.09.2014 09:33", "13.08.2014 15:52","11.09.2014 02:30")
d <- data.frame(ID, time)
d$time <- as.POSIXct(d$time, format="%d.%m.%Y %H:%M")
unlist(unname(lapply(split(d, d$ID), function(d) {
sapply(abs(diff(c(d$time[2], d$time))), function(x) {
sprintf("%s:%s", round(((x*24)%/%1)), round(((x*24)%%1 *60)))
})
})))
## [1] "94:59" "94:59" "682:38" "682:38"
我不得不相信这个功能已经存在于某处,不过。
类似于 David 和 hrmbrmstr 的尝试,我发现这个使用 difftime
的解决方案有效
我使用在 Whosebug 上找到的行移位脚本
rowShift <- function(x, shiftLen = 1L) {
r <- (1L + shiftLen):(length(x) + shiftLen)
r[r<1] <- NA
return(x[r])
}
d$time.c <- as.POSIXct(d$time, format = "%d.%m.%Y %H:%M")
d$time.prev <- rowShift(d$time.c,-1)
d$diff <- difftime(d$time.c,d$time.prev, units="hours")
d$diff
的每隔一行在结果中有 positive/negative 个值。我确实删除了所有具有负值的行,并且每个 ID 的第一次和最后一次之间存在差异。