我有一些不同日期的数据,想知道事件发生的平均(中位数或小时数)小时。问题在于,正常平均值在这里不起作用,因为时间是循环的(例如1在24之后出现)。例如,晚上11点和凌晨1点的平均值应该是午夜,但正常的平均值函数将给出午夜。但是,我找不到为此目的而构建的任何功能!有没有办法在R中做到这一点?
示例数据:
hours <- c(20, 21, 22, 23 , 0, 1, 2, 3, 4)
预期结果:平均值= 0,中位数= 0
答案 0 :(得分:3)
1)不断减少假设时间在不断减少,并且每次距上次时间均少于24小时,我们可以通过每次加1来确定每次的day
我们遇到的时间少于前一个小时。将一天中的24次添加到hour
中,得到hours2
,这是自小时0开始的总小时数。最后取均值或中值模24,以确保它在区间[0,24)中。 / p>
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
2)循环在这种替代方式中,我们将时间映射到一个圆圈,并使用循环包中的mean.circular
和median.circular
。有关该软件包的更多信息,请参见其帮助文件。
Answering biological questions using circular data and analysis in 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)
答案 1 :(得分:2)
对于圆形平均值,请执行以下操作:
我不知道圆形中位数是否存在公认的定义。
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