如何计算一个事件的平均小时数?

3
我有一些不同日期的数据,想知道事件发生的平均时间(中位数或平均数)。问题在于常规平均值在此处不起作用,因为时间是循环的(例如,1在24之后)。例如,11pm和1am的平均时间应该是午夜,但正常的平均函数会得出中午的结果。然而,我找不到任何内置函数来做到这一点!有没有办法在R中解决这个问题?
示例数据:
hours <- c(20, 21, 22, 23 , 0, 1, 2, 3, 4)

预期结果:平均值 = 0,中位数 = 0


也许这会带您走向正确的方向:https://dev59.com/F5_ha4cB1Zd3GeqPvDi7 - Kuba Do
你可以使用模运算 sum(hours)%%24 得到0。 - maydin
@maydin,这对中位数也适用吗? - Dunois
@Arcoutte 这里并不重要日期,我想知道的是大多数事件发生的时间。显然,当你有两个时间时(中午和午夜之间的平均值可能是上午6点或下午6点),这并不完全适用,但我有成千上万个数值。 - unknown
1
如果你的数据总是有序的,那么你可以直接找到中心点并选择作为中位数。如果不是,你需要解释哪一天的小时是那个。例如,如果你有一个像 c(9,10,11,12,13,14,15,16,17,18,20, 21, 22, 23 , 0, 1, 2, 3, 4,5,6,7,8,9) 这样的数据,你期望中位数的值是什么? - maydin
显示剩余6条评论
2个回答

5
1) 不减 假设时间是不减的,并且每个时间与前一个时间相差不超过24小时,我们可以通过在遇到比前一个小时小的小时数时每次加1来确定每个时间所属的day。将day乘以24并加上hour,得到hours2,即自hour 0开始的总小时数。最后对平均值或中位数进行模24运算,以确保它在区间[0, 24)内。
hours <- c(20, 21, 22, 23 , 0, 1, 2, 3, 4)

day <- cumsum(c(0, diff(hours) < 0))
hours2 <- hours + 24 * day

mean(hours2) %% 24
## [1] 0

median(hours2) %% 24
## [1] 0

在这种替代方案中,我们将时间映射到圆形上,并使用circular包中的mean.circular和median.circular。有关该包的更多信息可在其帮助文件以及使用R回答生物学问题的循环数据和分析中找到。
library(circular)

hours <- c(20, 21, 22, 23 , 0, 1, 2, 3, 4)

hours.circ <- circular(hours, template = "clock24", units = "hours")

mean.circ <- mean(hours.circ)
as.numeric(mean.circ) %% 24
## [1] 0

median.circ <- median(hours.circ)
as.numeric(median.circ) %% 24
## [1] 0

plot(hours.circ)
points(mean.circ, col = "red", cex = 3)
points(median.circ, col = "blue", cex = 2)

[图表后继续阅读]

屏幕截图

注意

您可能会发现使用更不对称的输入更有用。

hours <- c(20, 21, 22, 23 , 12)

2

对于圆形平均值,您需要执行以下操作:

  1. 通过将小时数乘以(2 * pi / 24)将其映射到24小时的圆形上。
  2. 分别计算平均x和y坐标。
  3. 将这些平均圆形坐标转换回小时数。

我不知道是否存在一个被广泛接受的圆形中位数定义。

average_time <- function(x) {

  circle_hours <- x*(2*pi/24)

  mean_x <- mean(cos(circle_hours))
  mean_y <- mean(sin(circle_hours))

  atan2(mean_y, mean_x) / (2*pi) * 24
}

hours <- c(20, 21, 22, 23 , 0, 1, 2, 3, 4)
average_time(hours)
## [1] -1.078441e-15

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接