Расчет скользящего стандартного отклонения по группам

У меня есть длинный набор данных в следующем формате:

Date         Country     Score
1995-01-01   Australia    100
1995-01-02   Australia     99
1995-01-03   Australia     85
:            :             :
:            :             :
2019-06-30   Australia     57
1995-01-01   Austria       67
1995-01-02   Austria       12
1995-01-03   Austria       10
:            :             :
:            :             :
2019-06-30   Austria       21  

Я хочу рассчитать скользящее стандартное отклонение оценки за 90-дневный период для каждой страны. Я пытался использовать функцию rollapply (Package:zoo) и roll_sd (Package:RcppRoll), но они не работают для группового стандартного отклонения. Может ли кто-нибудь предложить возможный способ расчета скользящего стандартного отклонения.

Спасибо!


person Arsh    schedule 25.11.2019    source источник
comment
Изучите пакет runner и примените любой функция на скользящих окнах. Поместите дату в аргумент idx и укажите k = 90 (90 дней). Даже если у вас есть пробелы в датах, компьютер по-прежнему использует 90 дней вместо 90 элементов. Дополнительные примеры приведены в другая виньетка   -  person GoGonzo    schedule 25.11.2019


Ответы (1)


Обычно группировка выполняется отдельно от базовой операции в R, поэтому эти функции нельзя использовать для сгруппированных данных. Просто вам нужно встроить их в операцию группировки. Здесь мы используем ave для группировки и rollapplyr для выполнения прокатки sd.

Теперь можем ли мы в каждой точке предположить, что последние 90 дней — это последние 90 строк? Предположим, что да, и взяв скользящее стандартное отклонение, равное 2, чтобы мы могли использовать выбранные строки опубликованных данных, воспроизводимых в примечании в конце:

library(zoo)

roll <- function(x) rollapplyr(x, 2, sd, fill = NA)
transform(DF, roll = ave(Score, Country, FUN = roll))

давая:

        Date   Country Score       roll
1 1995-01-01 Australia   100         NA
2 1995-01-02 Australia    99  0.7071068
3 1995-01-03 Australia    85  9.8994949
4 1995-01-01   Austria    67         NA
5 1995-01-02   Austria    12 38.8908730
6 1995-01-03   Austria    10  1.4142136

Подход к широкой форме

Другой подход заключается в преобразовании данных в расширенную форму и последующем выполнении операции прокатки:

library(zoo)
z <- read.zoo(DF, split = "Country")
zr <- rollapplyr(z, 2, sd, fill = NA)
zr

давая эту серию зоопарка:

           Australia   Austria
1995-01-01        NA        NA
1995-01-02 0.7071068 38.890873
1995-01-03 9.8994949  1.414214

Затем вы можете просто оставить его как серию зоопарка, чтобы воспользоваться другими функциями временных рядов в этом пакете, или можете преобразовать его обратно во фрейм данных, используя fortify.zoo(zr) или fortify.zoo(zr, melt = TRUE, names = names(DF)) в зависимости от того, что вам нужно.

Примечание

Ввод используется в воспроизводимой форме.

Lines <- "Date         Country     Score
1995-01-01   Australia    100
1995-01-02   Australia     99
1995-01-03   Australia     85
1995-01-01   Austria       67
1995-01-02   Austria       12
1995-01-03   Austria       10"
DF <- read.table(text = Lines, header = TRUE)
DF$Date <- as.Date(DF$Date)
person G. Grothendieck    schedule 25.11.2019