Преобразование кадра данных в объект TS в R - PullRequest
1 голос
/ 27 мая 2020

У меня есть фрейм данных, который выглядит так:

  DAY     X1996 X1997 
1 1-Jul    98    86   
2 2-Jul    97    90   
3 3-Jul    97    93   
....

Я хочу получить объект TS, чтобы я мог выполнять сглаживание HoltWinters на нем. Думаю, Я хочу, чтобы это выглядело вот так (хотя я не уверен, потому что раньше не делал HoltWinters):

Day    Year   Temp
1-Jul  1996   98
2-Jul  1996   98
3-Jul  1996   98
...
1-Jul  1997   86
2-Jul  1997   90
3-Jul  1997   93

Это то, что я пытаюсь сделать :

df <- read.delim("temps.txt")
myts <- as.ts(df)

Но это не похоже на то, что мне нужно для модели Холтвинтерса. Я просмотрел всю документацию по stackoverflow и TS и Zoo, и я застрял в том, как создать этот объект TS. Мы будем очень признательны за PU sh в правильном направлении.

1 Ответ

1 голос
/ 27 мая 2020
Объекты

ts обычно используются с данными за месяц, квартал или год, а не за день; однако, если мы удалим 29 февраля, тогда мы сможем создать объект ts, время которого равно году плюс дробная часть 0/365, 1/365, ..., 364/365, которые будут равномерно распределены, если нет пропущенных дат. Ключевым моментом является то, что если сезонность основана на году, то мы должны иметь одинаковое количество точек в каждом году, чтобы представить его как объект ts.

Сначала преобразовать в объект зоопарка z0, имеющий обычную дату удалите 29 февраля, указав z, создайте указатель времени, описанный выше, в объекте зоопарка zz, а затем преобразуйте его в ts.

library(data.table)
library(lubridate)
library(zoo)

m <- melt(as.data.table(df), id.vars = 1)
z0 <- with(m, zoo(value, as.Date(paste(variable, DAY), "X%Y %d-%b")))
z <- z0[! (month(time(z)) == 2 & day(time(z)) == 29)]  

tt <- time(z)
zz <- zoo(coredata(z), year(tt) + (yday(tt) - ((month(tt) > 2) & leap_year(tt)) - 1)/365)
as.ts(zz)

Удалить De c 31 в високосных годах

Выше мы удалили 29 февраля в високосные годы, но альтернативным подходом было бы удаление De c 31-го в високосные годы, что дает немного более простой код, который позволяет избежать необходимости использовать leap_year, поскольку мы можем просто удалить любой день, для которого yday равен 366. z0 - из выше.

zz0 <- z0[yday(time(z0)) <= 365]
tt <- time(zz0)
zz <- zoo(coredata(zz0), year(tt) + (yday(tt) - 1) / 365)
as.ts(zz)

Агрегирование по месяцам

Другой подход может сократить данные до ежемесячных данных. Тогда это относительно просто, поскольку ts имеет средства для представления ежемесячных данных. Ниже мы использовали последнюю точку каждого месяца, но при желании мы могли бы использовать среднее значение или другое скалярное обобщение.

ag <- aggregate(z0, as.yearmon, tail, 1)  # use last point in each month
as.ts(ag)

Примечание

df в вопросе, преобразованном в воспроизводимую форму, является следующие (однако нам нужно будет заполнить его дополнительными данными, чтобы избежать создания объекта ts с большим количеством NA).

df <- structure(list(DAY = structure(1:3, .Label = c("1-Jul", "2-Jul", 
"3-Jul"), class = "factor"), X1996 = c(98L, 97L, 97L), X1997 = c(86L, 
90L, 93L)), class = "data.frame", row.names = c("1", "2", "3"
))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...