Ссылка на предыдущий элемент в середине столбца в R

#r #for-loop

#r #для цикла

Вопрос:

У меня есть фрейм данных, в котором есть столбец даты и столбец совокупной суммы. Данные совокупной суммы заканчиваются в определенной точке, и я хочу использовать формулу для вычисления ее для остальных дат в столбце даты. С чем у меня возникают проблемы, так это с тем, что формула ссылается на предыдущую ячейку в столбце, начиная с того места, где счетчик возвращается к 0 (где заканчивается историческая совокупная сумма).

Пример ниже:

 dates.1 <- c("2016-12-06","2016-12-07","2016-12-08","2016-12-09","2016-12-10","2016-12-11","2016-12-12","2016-12-13","2016-12-14")
count.1 <- c(1,3,8,10,0,0,0,0,0)
drift <- .0456


df.1 <- data.frame(cbind(dates.1,count.1))


for (i in df.1$count.1) {
  if (i == 0) {
head(df.1$count.1, n = 1L) exp(drift (qnorm(runif(5,0,1))))
  }
}
  

Я не могу заставить цикл for правильно его вычислить.

Причина n = 5 для runif заключается в том, что это количество будущих записей, для которых я хочу запустить формулу.

Желаемый результат будет иметь что-то вроде

 print(df.1$count.1)

[1] 1 3 8 10 12 13 16 17 18
  

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

Есть идеи?

Комментарии:

1. Я удалил предложение «Я уверен, что это не слишком сложно, но, как новичок, я не совсем понимаю». по 2 причинам. Во-первых, поэтому ненужные комментарии в вопросах не поощряются. Другой заключается в том, что, когда вы просите людей о помощи, им не нравится, если вы говорите им, что проблема, которую вы просите их решить, проста, даже если вы не можете сделать это самостоятельно. Это умаляет их усилия и опыт.

2. Вы правы. Я сожалею об этом и буду иметь это в виду в своем следующем посте!

3. Не могли бы вы немного уточнить? Что вы добавляете, т. Е. Почему следующий элемент после 10 должен быть 12, откуда берется 2 и почему, например, это не 3? Кроме того, как drift и runif вписывается в эту картину?

4. Конечно, 12 и числа после являются чисто случайными, это был просто пример того, каким может быть возможный результат. Весь смысл этого в том, что в конечном итоге он станет частью модели прогнозирования, основанной на историческом тренде. Вот откуда берется часть дрейфа. Это вычисление, основанное на дисперсии и стандартном отклонении исторических данных. Часть qnorm(runif (…)) является лишь частью вычисления прогнозирования, которое должно добавляться к предыдущему числу

5. В этом случае, когда вы говорите: «Я не могу заставить цикл for правильно его вычислить». — что вы имеете в виду? Очевидно, что ваш код не будет выдавать указанные вами значения, поскольку они являются случайными.

Ответ №1:

Нет необходимости в цикле. Вы можете получить то, что хотите, сначала определив индекс строки, на котором cumsum остановлено:

 last.ind <- which(df.1$count.1==0)[1]-1
  

Затем используйте это last.ind , чтобы перезапустить cumsum :

 set.seed(123)  ## for reproducibility
## simulation of rest of data to cumulatively sum
rest.of.data <- exp(drift (qnorm(runif(5,0,1))))
df.1$count.1[last.ind:length(df.1$count.1)] <- cumsum(c(df.1$count.1[last.ind],rest.of.data))
print(df.1$count.1)
##[1]  1.00000  3.00000  8.00000 10.00000 10.59757 12.92824 13.75970 17.20085 22.17527
  

Если вы хотите использовать цикл, то вам следует выполнить следующее, что дает тот же результат, но будет медленнее:

 for (i in seq_len(length(df.1$count.1))) {
  if (df.1$count.1[i] == 0) {
    df.1$count.1[i] <- df.1$count.1[i-1]   exp(drift (qnorm(runif(1,0,1))))
  }
}
  

Примечания:

  1. Цикл по индексам значений df1$.count.1 not.
  2. Если значение в текущем индексе i равно 0 , запишите поверх этого значения сумму предыдущего значения at i-1 и данные, подлежащие кумулятивному суммированию.

Кроме того, вы не должны использовать cbind для создания своего data.frame . В этом случае это приведет к тому df.1$count.1 factor , что вместо numeric . Используемые данные:

Данные:

 df.1 <- structure(list(dates.1 = structure(1:9, .Label = c("2016-12-06", 
"2016-12-07", "2016-12-08", "2016-12-09", "2016-12-10", "2016-12-11", 
"2016-12-12", "2016-12-13", "2016-12-14"), class = "factor"), 
    count.1 = c(1, 3, 8, 10, 0, 0, 0, 0, 0)), .Names = c("dates.1", 
"count.1"), row.names = c(NA, -9L), class = "data.frame")
##     dates.1 count.1
##1 2016-12-06       1
##2 2016-12-07       3
##3 2016-12-08       8
##4 2016-12-09      10
##5 2016-12-10       0
##6 2016-12-11       0
##7 2016-12-12       0
##8 2016-12-13       0
##9 2016-12-14       0
  

Комментарии:

1. Это именно то, что я искал, большое спасибо за объяснение этого и за подсказку с cbind!