Р: ошибки при подведении итогов?

Я смоделировал (нормально распределенные) случайные данные для каждого дня за период с 1 января 2014 года по 1 января 2016 года. Затем я попытался взять итоги этих данных через регулярные периоды в 8 дней. Вот мой код (я добавил семя для воспроизводимости):

library(xts)
library(ggplot2)

set.seed(123)
    
#simulate data
    property_damages_in_dollars <- rnorm(731,100,10)

date_decision_made = seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
    
    date_decision_made <- format(as.Date(date_decision_made), "%Y/%m/%d")
    
final_data <- data.frame(date_decision_made, property_damages_in_dollars)

#convert to xts object
dat <- xts(final_data$property_damages_in_dollars, 
           as.Date(final_data$date_decision_made, '%Y/%m/%d'))

#aggregate by 8 day period
ep <- endpoints(dat,'days',k=8)

#final aggregated file
a = period.apply(x=dat,ep,FUN=sum )

#plot
a_df <- fortify(a)
 ggplot(a_df, aes(x = Index, y = a)) + geom_line()

Однако при суммировании данных за 8-дневный период наблюдаются значительные нерегулярные всплески, что позволяет предположить, что при суммировании данных могут быть некоторые ошибки:

введите здесь описание изображения

  1. Ближе к концу графика наблюдается падение. Это выглядит подозрительно, но отчасти объяснимо.

  2. В середине графика очень заметный резкий провал - это действительно похоже на ошибку расчета. Это падение происходит, когда год переходит с 2015 (декабрь) на 2016 год, соответствующие (агрегированные) числа, связанные с этим временем, также кажутся низкими.

Может ли кто-нибудь объяснить эти падения и предложить, как их можно исправить? Спасибо


person stats555    schedule 06.12.2020    source источник
comment
Глядя на даты, которые вы выделили, у вас есть 5-дневный период вместо 8-дневного, что соответствует падению в середине графика. Я не знаком с xts - вы можете заставить endpoints игнорировать конец года?   -  person Hobo    schedule 06.12.2020
comment
Спасибо за ваш ответ! Вы знаете, почему создается 5-дневный период, когда указан 8-дневный период? Вы знаете, как решить эту проблему? Спасибо еще раз!   -  person stats555    schedule 06.12.2020
comment
Извините, хотел сказать можете, а не можете. Глядя на справку для функции, нет очевидного исправления с endpoints. Вместо этого вы можете использовать seq - см. мой ответ   -  person Hobo    schedule 06.12.2020


Ответы (1)


Похоже, функция endpoints почему-то учитывает конец года. Но также похоже, что он просто создает числовой вектор, содержащий количество дней в каждом периоде. Поэтому замените его чем-то вроде

total_days <- 731
period_length <- 8

ep <- seq(0, total_days, period_length)
if (ep[length(ep)] < total_days) {
  ep[length(ep) + 1] <- total_days
}

кажется, работает. Я использовал if, потому что seq кажется коротким, если total_days не кратно period_length. Вероятно, есть более аккуратный способ: см. этот вопрос для возможных решений, если Вы заинтересованы.

Кажется, это исправляет среднее падение; последнее из-за того, что за этот период нет полных данных за 8 дней (я думаю).

person Hobo    schedule 06.12.2020
comment
спасибо! это, кажется, позаботилось о шипе в середине. Но можно ли исправить всплеск ближе к концу графика? Спасибо тебе за помощь! - person stats555; 06.12.2020
comment
Извините, только что увидел это. Всплеск в конце вызван тем, что 731 не кратно 8. Если вместо этого вы используете 736, это должно работать. Что-то вроде date_decision_made <- seq(as.Date("2014/1/1"), ,by="day", length.out = 736) - person Hobo; 06.12.2020
comment
Спасибо за ваш ответ - это имеет смысл, о том, какие числа делятся без остатка. Я был просто удивлен, что это деление может иметь такое видимое значение на графике, особенно в середине. Есть ли лучший способ агрегировать данные, чтобы компьютер сам позаботился об этих проблемах? Есть ли способ, чтобы отображались только полные периоды - например. если имеется 740 наблюдений и 8 дневных периодов, наблюдения 737, 738, 739, 740 не наносятся? Спасибо тебе за помощь! - person stats555; 07.12.2020
comment
С исходным ep средний период составляет 5 дней, а последний - 1 день, поэтому высота примерно такая, как я ожидал (5/8 и 1/8 высоты других периодов соответственно). Я думаю, что самый простой способ обеспечить отображение только полных периодов — это округлить количество дней в верхней части скрипта: whole_periods <- floor(days / days_per_period); days <- whole_periods * days_per_period. Хотя, когда вы используете реальные данные, вам придется выполнять вычисления на основе количества строк во фрейме данных, а затем брать верхние n строк. - person Hobo; 08.12.2020