R根据同一列中的前一个单元格值生成一个单元格值

R generating a cell value based on the previous cell value in that same column

我目前正在根据某些数据进行 运行 模拟。最终结果是生成一个列,其中第一个值基于一个公式,然后第二个、第三个和第四个值基于前一个值。 (例如条目 n°2 依赖于 n°1,n°3 依赖于 n°2)我已经通过 运行 使 mutate 函数重复 3 次来解决这个问题。但是,考虑到整洁,我想要么有一个短循环,要么使用其中一个应用函数一次执行所有 3 次重复。有什么建议吗?

这是一个例子:

sampleframe <- data.frame("value1" = c(15,18,22,19),
                          "value2" = c(12,14,13,12),
                          "parameter" = c(0.8,NA,NA,NA))

sampleframe <- sampleframe %>%
  mutate("value3" = value2 * parameter)

这会根据一个公式生成具有“value3”列第一行的数据框。然后我想生成最后 3 行。我运行这一行:

sampleframe <- sampleframe %>%
  mutate(`value3`= ifelse(is.na(value3) == FALSE,  value3,lag(value3) * value2))

在保留第一行值的同时生成第二行值。然后我必须 运行 相同的命令额外两次才能填充最后 2 行。它的工作原理是它保留以前的值,同时始终生成下一个值,但它似乎非常低效。回到我的问题,有没有更好的方法来做到这一点? (我假设有)

编辑: 鉴于 purrr 解决方案,我 运行 在扩展上面的示例时遇到以下问题。如果我想在表达式中添加一个常量,解决方案不再有效:

sampleframe <- sampleframe %>%
  mutate(`value3`= ifelse(is.na(value3) == FALSE,  value3,lag(value3) * value2 + value 1))

在咕噜声解决方案中:

sampleframe %>% 
  mutate(
    value3 = if_else(row_number() == 1, value2*parameter, value2),
    value3 = accumulate(value3, prod)
  )

value3中的每一项都将乘以值2。问题是在值2之后添加常量:

sampleframe %>% 
  mutate(
    value3 = if_else(row_number() == 1, value2*parameter, value2 + value1),
    value3 = accumulate(value3, prod)
  )

没有产生预期的结果,因为我不希望 value1 乘以 value2。在第二学期加入:

sampleframe %>% 
  mutate(
    value3 = if_else(row_number() == 1, value2*parameter, value2),
    value3 = accumulate(value3, prod) + value1
  )

也不起作用,因为它在最后添加了 value1 作为一个块,这意味着第 1 行和第 2 行计算正确,但第 3 行和第 4 行不正确。我尝试了任何我能想到的方法来使这个命令起作用,但我对 purrr 包不够熟悉,无法找到修复方法。有什么想法吗?

限制我对您当前方法的回答,您可以使用 for 循环提高效率:

number_iterations = 3

# setup
sampleframe <- data.frame("value1" = c(15,18,22,19),
                          "value2" = c(12,14,13,12),
                          "parameter" = c(0.8,NA,NA,NA))

sampleframe <- sampleframe %>%
  mutate("value3" = value2 * parameter)

# run
for(ii = 1:number_iterations){
  sampleframe <- sampleframe %>%
    mutate(`value3`= ifelse(is.na(value3) == FALSE,  value3,lag(value3) * value2))
}

四个循环将按照您在 number_iterations 中指定的次数处理代码的 运行。

但是,我通常会推荐像 mutate 这样的操作来一次处理整个列,而不是一次更新一个值。因此,您可能会通过研究不同的数据结构和解决方案方法进一步提高效率。

您可以使用 {purrr} 中的 accumulate() 并按顺序相乘。

sampleframe %>% 
  mutate(
    value3 = if_else(row_number() == 1, value2*parameter, value2),
    value3 = accumulate(value3, prod)
  )


#   value1 value2 parameter  value3
# 1     15     12       0.8     9.6
# 2     18     14        NA   134.4
# 3     22     13        NA  1747.2
# 4     19     12        NA 20966.4