У меня есть некоторые данные за разные даты, и я хочу знать, в какой средний (средний или средний) час происходят события. Проблема в том, что нормальные средние значения здесь не работают, поскольку время круговое (например, 1 следует после 24). Например, среднее время 11:00 и 1:00 должно быть полночь, но нормальная средняя функция даст полдень. Тем не менее, я не могу найти какие-либо функции, которые созданы для этого! Есть ли способ сделать это в R?

Пример данных:

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

Ожидаемый результат: среднее = 0, медиана = 0

2
unknown 19 Авг 2019 в 14:32

2 ответа

Лучший ответ

1) неубывающий Если предположить, что время не уменьшается и что каждый раз меньше 24 часов от предыдущего времени, мы можем определить day каждого времени, добавляя 1 каждый раз, когда встречаем час, который меньше, чем предыдущий час. Добавьте 24 раза в день к hour, давая hours2, который является общим числом часов с часа 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

2) круговой . В этой альтернативе мы отображаем время в круг и используем 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)

[продолжение после графика]

screenshot

Заметка

Вы также можете попробовать использовать вышесказанное с более асимметричным вводом.

hours <- c(20, 21, 22, 23 , 12)
3
G. Grothendieck 20 Авг 2019 в 02:44

Для кругового среднего вы делаете следующее:

  1. Сопоставьте часы с кругом 24 часа, умножив их на (2 * пи / 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
2
Aron 19 Авг 2019 в 13:10