Распространение данных временных рядов с помощью непрерывной строки NA - PullRequest
0 голосов
/ 10 января 2019

Итак, у меня есть некоторые данные временных рядов, которые должны быть ежедневными, но обычно испытывают прерывания различной длины. Например, в идеальном мире данные будут выглядеть примерно так (вперёд во времени):

1, 1, 3, 2, 4, 1, 1, 5, 6, 5, 6 --- (1)

Но вместо этого получается так:

NA, NA, 5, 2, 4, NA, 2, NA, NA, NA, 22 --- (2)

Я буду выбирать из этих данных для моделирования Монте-Карло, но строки NA, за которыми следует большое число, будут явно искажать среднее значение данных, если я просто проигнорирую NA или стандартное отклонение, если я установлю их в 0.

Я хочу равномерно распределить данные по цепочке NA, в зависимости от их длины.

Например, в (2) равномерно развернутая версия будет выглядеть примерно так:

1,67, 1,67, 1,67, 2, 4, 1, 1, 5,5, 5,5, 5,5, 5,5

Или более точно:

5/3, 5/3, 5/3, 2, 4, 2/2, 2/2, 22/4, 22/4, 22/4, 22/4

Таким образом, окончательным значением NA будет (Значение, следующее за строкой NA) / (длина непрерывных дней NA, в которых она существует + 1)

Раньше я использовал цикл for, который пробегал временной ряд день за днем, затем, когда он сталкивался с NA, подсчитывал и увеличивал до достижения значения не-NA, затем брал это значение не-NA и делил его счетчиком + 1 и замените предыдущие NA этим значением на другой цикл for, который, очевидно, довольно медленный.

Кроме того, данные существуют во фрейме данных, сгруппированном по 2 идентификаторам группировки, содержащим временные ряды для каждой уникальной комбинации двух идентификаторов группировки, поэтому заранее я поднастроил их для получения одного временного ряда за раз. Если код мог бы работать намного быстрее без этого шага, то я в порядке, удалив его.

Код в R можно увидеть ниже:

newtest - основной фрейм данных, а eventest - выходной. X, Y, Z - переменные значения, которые должны распределяться равномерно. Я также ограничиваю вечер 4 днями, но не против, если бы он прошел весь путь. Я знаю, что привязка строк к растущему информационному фрейму - ужасная практика, и я работаю над методом вставки для начального даже самого начального теста, такого же размера, как и самый новый, но заполненного NA. Тем не менее, я думаю, что главным узким местом является цикл for, поэтому я спрашиваю, может ли быть лучший способ сделать это.

eventest <- newtest [0,] </p>

count <- 0 </p>

для (я в уникальном (newtest $ group_id1)) {

newtest0 <- подмножество (newtest, group_id1 == i) </p>

для (j в уникальном (newtest0 $ Color)) {

count <- count + 1

if(count%%200 == 0){print(count)}

newtest1 <- subset(newtest0, group_id2 == j)

counter <- 0

for (n in 1:nrow(newtest1)){

  if(is.na(newtest1$Level_Delta[n])){

    counter <- counter + 1

    ErrorReport <- rbind(ErrorReport, c(i, j, "Missing Intermediate Date", as.character(newtest1$Date[n])))

  } else if (counter >= 1 & counter <= 4){

    finalx <- newtest1$X[n]

    finaly <- newtest1$Y[n]

    finalz <- newtest1$Z[n]

    for(m in 0:counter){

      newtest1$X[n-m] <- finalx/(counter+1)

      newtest1$Y[n-m] <- finaly/(counter+1)

      newtest1$Z[n-m] <- finalz/(counter+1)

    }

    counter <- 0

  } else {counter <- 0}

}

eventest <- rbind(eventest, newtest1)}}

Пробная версия, над которой работал этот код, заняла около 2 часов. Тем не менее, новинка в конце дня будет примерно в 50 раз больше, поэтому у меня возникают проблемы во время выполнения. Это работает, но это занимает слишком много времени.

newtest также находится в базе данных SQL Server (он считывается в R с использованием odbc), так что если это можно каким-то образом сделать на SQL Server, используя запрос, который был бы неплохим.

Любая помощь будет оценена. Спасибо!

...