#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))))
}
}
Примечания:
- Цикл по индексам значений
df1$.count.1
not. - Если значение в текущем индексе
i
равно0
, запишите поверх этого значения сумму предыдущего значения ati-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!