R不知道时间是循环的吗?如何查找一天中最接近给定时间的时间

时间:2019-05-27 10:17:25

标签: r date difference

例如,

23:59:59接近午夜,而不是03:00:00接近午夜。不幸的是,R却相反(至少我使用的是包装)。这是我的意思:

image

事实上,我不仅在乎午夜,而且我需要在向量中找到与给定时间最接近的一天,而我不在乎日期。有一个类似的问题,其中的answer很好,但是该代码无法按预期工作,因为在链接时间中,时间轴不是圆圈。看到这里:

library("chron")
x <- times(c("00:00:02", "23:59:59"))
v <- times("00:00:00")
indx <- which(abs(x-v) == min(abs(x - v)))
x[indx]
00:00:02 # which is further from 00:00:00 than 23:59:59

根据代码,从00:00:00到23:59:59的所有时间始终比23:59:59更接近中间位置。例如,这导致令人困惑的结果,即16:23:11比23:59:59更接近午夜。因此,R似乎开始于00:00:00并结束于23:59:59,因此“看不到” 23:59:59非常接近00:00:00。我了解如果考虑到日期,这是有道理的:例如,2001-01-01 00:00:02比2001-01-01 23:59更接近2001-01-01 00:00:00: 59至2001-01-01 00:00:00。但是如何找到将时间视为一个圆圈的一天中最接近的时间?

1 个答案:

答案 0 :(得分:1)

由于chron没有很好的功能来执行此操作,并且我无法提出使用times数据类型的解决方案,因此我将放弃time而使用POSIXct。

POSIXct还具有您说不想使用的date属性。这就是为什么POSIXct中的日期只是一个我们真正不希望看到的虚拟值,只是以解决问题的方式对其进行了更改。

<a href="./image.jpg" download>
  <img src="./image.jpg" alt="W3Schools" width="104" height="142">
</a>

请注意,您现在可能希望使用x <- c("00:00:02", "23:59:59") x <- as.POSIXct(x, format = "%H:%M:%OS") v <- as.POSIXct("00:00:00", format = "%H:%M:%OS") # I subtract 24 hours to center all times around the same midnight. mid.day <- as.POSIXct("12:00:00", format = "%H:%M:%OS") x[x > mid.day] <- x[x > mid.day] - 24*60*60 # I used your same approach to check the time closest to midnight. # you might want to change this to something that uses difftime(). Ask me if you need help with this. indx <- which(abs(x-v) == min(abs(x - v))) # shows us the POSIXct object the way we want to see it (only time) format(x[indx], format="%H:%M:%S") 来获取时间差

difftime(x,y)

编辑以获取更通用的解决方案:

由于上述解决方案仅适用于非常特殊的情况,因此我尝试创建一个更通用的解决方案。我创建了一个函数,可以在最接近给定时间的向量中找到时间。

 indx <- which(abs(difftime(x, v)) == min(abs(difftime(x, v))))

此解决方案基于以下两种想法。第一个只是正常的顺时针距离。第二个是逆时针距离。由于整个圆圈为24小时,因此逆时针距离为'24_hours-clockwise_distance'。

然后对于timesVector中的每个值,应检查顺时针或逆时针距离是否最短。

最后,应该检查#' This function returns the time in 'timeVector' that is #' closest to 'time' closest.time <- function(timeVector, time) { times() x <- times(timeVector) v <- times(time) clockwise_distance = abs(x - v) anticlockwise_distance = times("23:59:59") - clockwise_distance + times("00:00:01") clockwise_and_anticlockwise <- matrix(c(anticlockwise_distance, clockwise_distance), ncol = 2) shortest_distance_of_the_two <- apply(clockwise_and_anticlockwise, 1, min) indx <- which(shortest_distance_of_the_two == min(shortest_distance_of_the_two)) x[indx] } 中哪个时间最接近timeVector