【发布时间】:2020-02-12 10:59:43
【问题描述】:
我有一个表格,其中包含不同产品的历史每日价格数据和未来价格的 NA。我有一列关于产品在给定未来日期的预期价格上涨。价格上涨是基于前一天的价格。
我已经构建了一个 for 循环来计算产品的预期价格,但是对于它正在循环的约 500,000 条记录,它的运行速度非常慢。
所有历史价格数据都在表中,而所有预测价格均为NA。
当前表(old_table)示例:
date product price incr_amt
====================================================
... ... ... ...
10/14/19 prod1 50 1.0
10/15/19 prod1 50 1.0
10/16/19 prod1 NA 1.0
... ... ... ...
04/01/20 prod1 NA 1.05
04/02/20 prod1 NA 1.0
... ... ... ...
... ... ... ...
10/14/19 prod2 35 1.0
10/15/19 prod2 35 1.0
10/16/19 prod2 NA 1.0
... ... ... ...
01/01/20 prod2 NA 1.02
01/02/20 prod2 NA 1.0
... ... ... ...
我当前的代码按产品分组,如果价格为 NA,则将价格计算为滞后价格 * increase_amt。然后为下一次迭代重新计算 laagged_price。 循环直到表格中的所有行。
示例结果(new_table):
date product price incr_amt
====================================================
... ... ... ...
10/14/19 prod1 50 1.0
10/15/19 prod1 50 1.0
10/16/19 prod1 50 1.0
... ... ... ...
04/01/20 prod1 52.5 1.05
04/02/20 prod1 52.5 1.0
... ... ... ...
... ... ... ...
10/14/19 prod2 35 1.0
10/15/19 prod2 35 1.0
10/16/19 prod2 35 1.0
... ... ... ...
01/01/20 prod2 35.7 1.02
01/02/20 prod2 35.7 1.0
... ... ... ...
我当前的代码可以运行,但运行需要一个多小时。因为每次迭代都依赖于之前的迭代并且顺序很重要,所以我不知道是否有使用循环的解决方法。
当前代码:
library(tidyverse)
old_table <- tribble(
~date, ~product, ~price, ~incr_amt,
"2019-10-14", "prod1", 50, 1.0,
"2019-10-15", "prod1", 50, 1.0,
"2019-10-16", "prod1", NA, 1.0,
"2019-10-17", "prod1", NA, 1.0,
"2019-10-18", "prod1", NA, 1.0,
"2019-10-19", "prod1", NA, 1.05,
"2019-10-20", "prod1", NA, 1.0,
"2019-10-21", "prod1", NA, 1.0,
"2019-10-14", "prod2", 35, 1.0,
"2019-10-15", "prod2", 35, 1.0,
"2019-10-16", "prod2", NA, 1.0,
"2019-10-17", "prod2", NA, 1.0,
"2019-10-18", "prod2", NA, 1.0,
"2019-10-19", "prod2", NA, 1.0,
"2019-10-20", "prod2", NA, 1.0,
"2019-10-21", "prod2", NA, 1.02,
"2019-10-22", "prod2", NA, 1.0
)
new_table <- old_table %>%
group_by(product) %>%
mutate(lag_price = lag(price))
for (i in 1:nrow(new_table)) {
if (!is.na(new_table$price[[i]]))
next
if (is.na(new_table$price[[i]])) {
new_table$price[[i]] = new_table$lag_price[[i]] * new_table$incr_amt[[i]]
new_table$lag_price <- lag(new_table$price)
}
}
代码运行,但需要一个多小时才能遍历约 500,000 条记录。我该如何改进这个过程?谢谢。
【问题讨论】:
-
您能否通过包括一些示例数据和输出来使您的重现性? (您的示例表总比没有好,但我无法将它们按原样加载到 R 中——有很多缺失的行需要我推断出您想要的内容。)
-
我已更新原始帖子以包含示例表。我希望澄清。谢谢。
-
导致循环变慢的至少部分原因是您正在修改表 500,000 次,这相当于将表复制到内存中的新位置、编辑它并更新指针。见the R inferno。
标签: r loops for-loop while-loop