R不知道时间是循环的吗?如何查找一天中最接近给定时间的时间 [英] Does R not know that time is circular? How to find closest time of the day to a given time

查看:49
本文介绍了R不知道时间是循环的吗?如何查找一天中最接近给定时间的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

23:59:59 o'clock is closer to midnight than 03:00:00 o'clock to midnight, for example. Unfortunately, R tells the opposite (at least the package I use). Here is what I mean:

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

In fact I do not only care about midnight but I need to find the closest time of the day in a vector to a given time and I do not care about the date. There is a similiar question with a great answer but the code doesn't work as expected because in the link time is a timeline not a circle. See here:

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.但是如何找到将时间视为一个圆圈的一天中最接近的时间?

According to the code all times between 00:00:00 and 23:59:59 are closer to midnigth than 23:59:59. For example, this leads to the confusing result that 16:23:11 is closer to midnight than 23:59:59. So R seems to start at 00:00:00 and end at 23:59:59 and thus "does not see" that 23:59:59 is pretty close to 00:00:00. I understand that this makes sense if we take into account dates: For example, 2001-01-01 00:00:02 is closer to 2001-01-01 00:00:00 than is 2001-01-01 23:59:59 to 2001-01-01 00:00:00. But how to find the closest time of the day where one considers the time as a circle?

推荐答案

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

如果您只是在寻找解决此问题的通用解决方案:

Edit for a more general solution:

If you are just looking for a nice general solution for this problem:

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

Since this solution above is only applicable for a very specific situation I tried to create a more general solution. I created a function that wil find to time in a vector closest to a given time.

library('chron')

#' 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]
}

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

This solution is based on the idea that there are two ways to go round the circle. The first is just the normal clockwise distance. The second is the anticlockwise distance. Since the whole circle is 24 hours, the anticlockwise distance is '24_hours - clockwise_distance'.

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

Then for each value in timesVector there should be checked if the clockwise or anticlockwise distance is the shortest.

最后,应该检查 timeVector 中的哪个时间最接近 time

Lastly, there should be checked which time in timeVector is closest to time

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

Since chron does not have a nice function to do this and I can't come up with a solution that uses the times data type, I am going to abandon times and use POSIXct instead.

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

POSIXct also has a date attribute that you said you don't want to use. This is why the date in our POSIXct is just a dummy value that we don't really look at, except for changing it in ways to solve our problem.

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)来获取时间差

Note that you might want to use difftime(x,y) now to get the difference in time

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

这篇关于R不知道时间是循环的吗?如何查找一天中最接近给定时间的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆