我有一个包含以下列的数据框,表示事件的开始和结束时间:
fh_ini fh_end
1 2015-12-07 00:00:00 2015-12-07 00:00:00
2 2015-12-07 00:00:00 2015-12-07 09:52:46
3 2015-12-07 09:20:13 2015-12-07 09:20:19
4 2015-12-07 09:20:22 2015-12-07 09:36:38
5 2015-12-07 09:40:49 2015-12-07 09:41:05
6 2015-12-07 09:45:12 2015-12-07 09:46:05
我想将fh_end和fh_ini之间的时差分成每个1小时的块,并计算每个块中的分钟数。
目的是计算所有事件和每个块的总时间(例如,00:00到01:00之间的块等)。
我对R很陌生,我不确定我是否可以使用现有函数实际执行此操作,或者我是否应该编写代码(使用循环?)来执行此操作。
我期待的结果如下(来自Excel)。第二排3:00到4:00之间的差距只有42分钟和37秒。
0:00 1:00 2:00 3:00 4:00
07/12/2015 1:00:00 07/12/2015 3:00:00 0 1 1 0 0
07/12/2015 0:00:00 07/12/2015 3:42:37 1 1 1 0,710277778 0
如果我只有2行,例如,每个块的结果总事件时间(以小时为单位)将是:
0:00 1:00 2:00 3:00 4:00
1 2 2 0,710277778 0
我想知道是否将时差分解是创建这个块的关键,但我已经尝试过在24个块中创建1天的因子并以相同的方式分解difftime并且我不知道该怎么做做下一个。无论如何,我不确定是否有任何其他方法可以获得不涉及对difftime进行分解的结果。
帮助将不胜感激!
答案 0 :(得分:0)
chron
包提供了处理日期和时间的实用程序。特别是,您可以使用times
函数,该函数将格式为hh:mm:ss
的字符串转换为times
个对象。可以添加和减去此格式的数据,并使用<
,>
,max
和min
等功能进行比较。试着玩它来了解一切是如何运作的!
您首先要将字符串中的fh_ini
和fh_end
列转换为时间对象。我会删除日期,只关注时间:
library(chron)
to_times <- function(vec) {
str_times <- sapply(strsplit(dtimes, ' '), `[`, 2)
times(str_times)
}
your_data$fh_ini_times <- to_times(your_data$fh_ini)
your_data$fh_end_times <- to_times(your_data$fh_end)
你的数据已经很方便了,所以我在这里所做的就是在空格上分割你的字符串,将它们分成日期和时间对列表,抓住列表中每个条目的第二个元素,然后转换然后转换从字符串到时间。
我这样做的方法是编写一个占用开始时间,结束时间和块的函数,并返回重叠量。我在下面写了一个例子 - 为了便于阅读,我在冗长的一面做了一点,并清楚地展示了你可以用times
数据类型做些什么。
block_check <- function(range_start, range_end, block_start) {
start_check <- (range_start < block_start + times("01:00:00"))
end_check <- (range_end > block_start)
if (start_check & end_check) {
o_start <- max(block_start, range_start)
o_end <- min(block_start + times("01:00:00"), range_end)
return(o_end - o_start)
} else {
return(times("00:00:00"))
}
}
如果你打破这个功能,我只是(1)检查start_time
和end_time
定义的范围是否与给定的1小时块重叠,如果它确实返回了多少重叠是
使用此功能后,您可以使用mapply
将其应用于数据集中的每个开始/结束时间对,如下所示:
z <- mapply(FUN = block_check, your_data$fh_ini_times, your_data$fh_end_times,
MoreArgs = list(block_start = times("01:00:00")))
your_data[,"1:00"] <- times(z)
对于你的24个时间段中的每一个都必须执行上述操作,这是笨拙和无聊的。如果你希望得到想象并一次完成所有事情,而不是分别对每个块,你可以遍历一个块列表。在这里,我使用stringr
包创建了一个块开始时间(作为字符串)的向量,然后依次将该函数从之前应用到每个元素(作为时间)(使用时间的字符串版本)命名数据框的结果列。)
library(stringr)
blocks <- str_c(as.character(0:23), ":00:00")
f <- function(block) {
z <- mapply(FUN = block_check, your_data$fh_ini_times, your_data$fh_end_times,
MoreArgs = list(block_start = block))
times(z)
}
for (block in blocks) {
your_data[, block] <- f(times(block))
}