Подстановка данных временных рядов на 3 дня и сохранение в списке - PullRequest
0 голосов
/ 03 ноября 2018

Временные ряды с дополнительными настройками на 3 дня и сохранение в списке. Таким образом, пусть предположим, что первое подмножество от day 1 to day 3, тогда второе подмножество будет от day 2 to day 4, так что каждое подмножество имеет данные за 3 дня. Обратите внимание, что это отметка времени данных 10 минут. И сохранение каждого подмножества в списке в зависимости от общего числа дней, доступных в данных. Я попытался воспроизвести это.

 time_10 <- seq(ISOdatetime(2001,2,1,0,0,0), ISOdatetime(2001,3,31,0,0,0), by=(200))

    a <- as.data.frame(matrix(, nrow = length(time_10), ncol = 4))
    names(a)<- c("time_10","var1","var2","var3")
    a$time_10 <- time_10
    a$var1 <- runif(nrow(a), min=20, max=70)
    a$var2 <- runif(nrow(a), min=10, max=50)
    a$var3 <- runif(nrow(a), min= 3, max=10)
    head(a)  

enter image description here

Вот изображение, которое я прилагаю, которое даст представление о настройке данных временного ряда и сохранении их в списке. Здесь D1: день1, D2: день2, D3: день3 соответственно. Использование цикла For или любого другого оптимального метода приветствуется. Примечание. Таким образом, внутри цикла For будут продолжаться 3 дня поднабора данных, которые сохраняются в списке с индексом как (Subset_n), где n - номер подмножества.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Это похоже на работу для вашего случая. Что я делаю, так это извлекаю дату и бросаю 3-дневное окно (ww) от начала до конца Для каждого шага я размещаю data.frame на основе дней в окне и сохраняю их в виде списка.

time_10 <- seq(ISOdatetime(2001,2,1,0,0,0), ISOdatetime(2001,3,31,0,0,0), by=(200))
var1 <- runif(length(time_10), min=20, max=70)
var2 <- runif(length(time_10), min=50, max=90)
var3 <- runif(length(time_10), min=50, max=90)

a <- as.data.frame(matrix(, nrow = length(time_10), ncol = 4))
names(a)<- c("time_10","var1","var2","var3")
a$time_10 <- time_10
a$var1 <- var1
a$var2 <- var2
a$var3 <- var3

date <- strptime(a$time_10, format = "%Y-%m-%d")
td10 <- sort(unique(date))

ww <- 3
out <- vector("list", length(td10) - round(ww/2))  # preallocate a list

for (i in 1:length(td10)) {
  bb <- i:(i + ww - 1) # this is the bounding box

  if (max(bb) > length(td10)) {
    message("End of time series reached, exiting.")
    return(NULL)
  }

  out[[i]] <- a[date %in% td10[bb], ]
}

# check ranges of dates for each subset
lapply(out, FUN = function(x) range(x$time_10))
0 голосов
/ 03 ноября 2018

Я полагаю, что следующий код выполняет то, что запрашивается. Он использует функцию minutes из пакета lubridate для упрощения арифметики даты и времени.

days3 <- lubridate::days(3)
d1 <- a$time_10[1]
d2 <- a$time_10[nrow(a)] - lubridate::days(2)

res <- lapply(seq(d1, d2, by = "1 days"), function(d){
  i <- which(d <= a$time_10 & a$time_10 < d + days3)
  a[i, ]
})

Edit.
Я нахожу количество строк в каждом кадре данных res громоздким, что затрудняет проверку того, действительно ли приведенный выше код дает ожидаемый результат. Вот способ проверить это.

check <- lapply(res, function(DF) lubridate::day(DF$time_10))
check <- sapply(check, function(x) rle(x)$values)
head(check, 3)
#[[1]]
#[1] 1 2 3
#
#[[2]]
#[1] 2 3 4
#
#[[3]]
#[1] 3 4 5

rm(check)    # tidy up

Данные.

Я опубликую код создания данных, поскольку оригинал не был воспроизводим.

set.seed(8893)

time_10 <- seq(ISOdatetime(2001,2,1,0,0,0), ISOdatetime(2001,3,31,0,0,0), by=(200))
var1 <- runif(length(time_10), min=20, max=70)
var2 <- runif(length(time_10), min=50, max=90)
var3 <- runif(length(time_10), min=50, max=90)

a <- data.frame(time_10, var1, var2, var3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...