Создать массив дат начала / конца дня в R
Я использую R, чтобы провести анализ временных рядов, используя zoo и chron. У меня есть объект зоопарка с большим количеством данных, и мне нужно иметь возможность использовать window
функция для подстановки данных только на один день, затем на следующие дни, затем на следующие и т. д.
Я попытался найти самый простой способ создания массива с датой каждого дня в определенном периоде и придумал следующее:
orig = c(month=1, day=1, year=2005)
dates <- chron(1:1825, origin=orig, out.format=c(dates="d/m/y", times="h:m"))
Здесь используется нотация юлианского дня, и она имеет 1825 дней (365*5, то есть пять лет), начиная с первого дня моего периода дат. Затем я пытаюсь сделать цикл for, используя каждый из элементов этого массива:
for (date in dates)
{
s = chron(date, "00:00:00", origin=orig)
e = chron(date, "23:59:59", origin=orig)
aeronet_day = window(aeronet, start=s, end=e)
}
Тем не менее, это дает мне предупреждение о том, что я использую разные источники для aeronet
зоопарк объект и s
а также e
переменные, и он не выбирает никаких данных.
Есть лучший способ сделать это? Или способ это исправить? По сути, я хочу запустить цикл for, где в цикле я могу использовать aeronet_day = window(aeronet, start=s, end=e)
код для создания объекта зоопарка, содержащего данные за один день (например, 1 мая 2005 года с 00:00:00 до 23:59:59.
3 ответа
Предположим, у нас есть эти данные:
# create test data
library(zoo)
library(chron)
z <- zooreg(1:30, start = chron("2000-01-01"), freq = 2)
1) агрегат R aggregate
Функция имеет зоопарк метод. Второй аргумент - это то, чем мы агрегируем. Если это функция, она применяется к индексу объекта зоопарка. например, здесь мы вычисляем среднее значение для каждой даты:
z.ag <- aggregate(z, as.Date, mean)
Мы можем заменить mean
с более сложной функцией, если мы хотим.
2) сплит. R split
Функция имеет зоопарк метод. Если мы действительно хотим разделить z
по дате мы можем это сделать. Вот z.split.list
список, каждый из компонентов которого содержит объект зоопарка на одну дату.
z.split.list <- split(z, as.Date(time(z)))
Сейчас (а) sapply
или (б) lapply
по этому списку или (с) используйте следующее (заменяя print(zc)
с какой обработкой желательно). Вот zc
является компонентом списка, т. е. это объект зоопарка, сформированный путем взятия определенной даты:
for(zc in z.split.list) print(zc)
Обратите внимание, что as.Date(time(z))
вектор с датами, соответствующими элементам z.
РЕДАКТИРОВАТЬ:
Различные незначительные разработки.
Если вы хотите делать что-то на основе даты, то у вас все в порядке.
Некоторый образец aeronet
данные.
last_date <- 1825
n <- 10000
aeronet <- data.frame(
some.value = seq_len(n),
date = as.chron(
runif(n, 0, last_date),
origin = orig,
out.format = c(dates = "d/m/y", times = "h:m")
)
)
Теперь вы можете разделить данные по дате, используя split
или применить функцию к каждой дате с tapply
или же ddply
от plyr
(или использовать aggregate
или что угодно).
with(aeronet, split(some.value, date))
with(aeronet, tapply(some.value, date, sum))
library(plyr)
ddply(aeronet, .(date), summarise, sum(some.value))
Я не знаком с зоопарком, но обычно я просто конвертирую дату в числовое значение, затем создаю последовательность, а затем снова конвертирую. Например:
> as.Date(Sys.Date():(Sys.Date()+365), origin='1970-01-01')
[1] "2011-12-06" "2011-12-07" "2011-12-08" "2011-12-09" "2011-12-10" "2011-12-11" "2011-12-12" "2011-12-13"
[9] "2011-12-14" "2011-12-15" "2011-12-16" "2011-12-17" "2011-12-18" "2011-12-19" "2011-12-20" "2011-12-21"
[17] "2011-12-22" "2011-12-23" "2011-12-24" "2011-12-25" "2011-12-26" "2011-12-27" "2011-12-28" "2011-12-29"
[25] "2011-12-30" "2011-12-31" "2012-01-01" "2012-01-02" "2012-01-03" "2012-01-04" "2012-01-05" "2012-01-06"
[33] "2012-01-07" "2012-01-08" "2012-01-09" "2012-01-10" "2012-01-11" "2012-01-12" "2012-01-13" "2012-01-14"
[41] "2012-01-15" "2012-01-16" "2012-01-17" "2012-01-18" "2012-01-19" "2012-01-20" "2012-01-21" "2012-01-22"
...