我正在尝试使用tidyverse来避免在模拟中使用循环。我有一个数据集与4个关键变量。它们都是相互依赖的,每个计算都需要逐行顺序处理。让我们用这个小示例来说明我的问题:
library(tidyverse)
df <- tibble(var_1 = c(250,190,120,150),
var_2 = c(200,NA,NA,NA),
var_3 = c(100,NA,NA,NA),
var_4 = c(1,NA,NA,NA))
var_3本质上是一个库存代理。我需要计算var_1 w.r.到var_2来确定是否有变化。如果有变化,var_3会减少一个单位,然后var_4也会改变。在随后的每一步中,var_2的计算都依赖于var_4。
这是我需要完成的计算类型的一个示例。它在循环中工作得很好:
for (i in 2:4) {
df$var_3[i] <- case_when(lag(df$var_1)[i] >= lag(df$var_2)[i] ~ lag(df$var_3)[i] - 1,
TRUE ~ lag(df$var_3)[i])
df$var_4[i] <- case_when(df$var_3[i] < lag(df$var_3)[i] ~ lag(df$var_4)[i] - 0.1,
TRUE ~ lag(df$var_4)[i])
df$var_2[i] <- lag(df$var_2)[i] * df$var_4[i]
}
运行上面的代码得到:
# A tibble: 4 × 4
var_1 var_2 var_3 var_4
<dbl> <dbl> <dbl> <dbl>
1 250 200 100 1
2 190 180 99 0.9
3 120 144 98 0.8
4 150 115. 98 0.8
在循环中,我基本上是比较第n-1行中的值来获得第n行中的值,以此类推。我在运行purrr
时遇到的主要问题是,它似乎没有按顺序运行操作,这是必要的。我没有设法使var_3减少,即使我为其他因变量发明了值。
你知道这个例子如何在宇宙中得到巩固吗?
我认为你必须使用循环,因为每一行都取决于上面一行的先前计算,但你可以使用这个函数
fNext <- function(df , i) {
if(df$var_1[i] >= df$var_2[i]) df$var_3[i+1] <- df$var_3[i] - 1
else {df$var_3[i+1] <- df$var_3[i]}
if(df$var_3[i+1] < df$var_3[i]) df$var_4[i+1] <- df$var_4[i] - .1
else {df$var_4[i+1] <- df$var_4[i]}
df$var_2[i+1] <- df$var_2[i] * df$var_4[i+1]
df
}
然后申请
for(i in 1:(nrow(df)-1)){
df <- fNext(df ,i)
}