在Excel中,通过引用先前的单元格可以很容易地对先前的单元格执行计算。例如,从初始值100(步骤= 0)开始,只需将公式栏从第一个单元格向下拖动(步骤= 1),每个下一个步骤就是0.9 * previous + 9。接下来的10个步骤如下所示:

      step     value
 [1,]    0 100.00000
 [2,]    1  99.00000
 [3,]    2  98.10000
 [4,]    3  97.29000
 [5,]    4  96.56100
 [6,]    5  95.90490
 [7,]    6  95.31441
 [8,]    7  94.78297
 [9,]    8  94.30467
[10,]    9  93.87420
[11,]   10  93.48678

我环顾了网络和StackOverflow,我能想到的最好的方法是for循环(如下)。有更有效的方法来做到这一点吗?是否可以避免for循环?似乎R中的大多数函数(例如cumsumdiffapply等)都在现有矢量上运行,而不是即时计算以前的值。
#for loop.  This works
value <- 100   #Initial value
for(i in 2:11) {
  current <- 0.9 * value[i-1] + 9
  value <- append(value, current)
}
cbind(step = 0:10, value)  #Prints the example output shown above

最佳答案

似乎您正在寻找一种在R中进行递归计算的方法。BaseR有两种执行此方法的方法,它们的区别在于用于执行递归的函数的形式。这两种方法都可以用于您的示例。
Reduce可以与v[i+1] = function(v[i], x[i])形式的递归方程一起使用,其中v是计算出的向量,而x是输入向量;即,在i+1输出仅取决于所计算和输入向量的第i个值的情况下,由function(v, x)执行的计算可能是非线性的。对于您来说,这将是

    value <- 100
    nout <- 10
# v[i+1]  =  function(v[i], x[i])
    v <- Reduce(function(v, x) .9*v  + 9, x=numeric(nout),  init=value, accumulate=TRUE)
    cbind(step = 0:nout, v)
filtery[i+1] = x[i] + filter[1]*y[i-1] + ... + filter[p]*y[i-p]形式的递归方程一起使用,其中y是计算出的向量,而x是输入向量;即输出可以线性地取决于计算出的向量的滞后值以及输入向量的i-th值。对于您的情况,这将是:
    value <- 100
     nout <- 10
# y[i+1] = x[i] + filter[1]*y[i-1] + ... + filter[p]*y[i-p]
        y <- c(value, stats::filter(x=rep(9, nout), filter=.9, method="recursive", sides=1, init=value))
     cbind(step = 0:nout, y)

对于这两个函数,输出的长度由输入矢量x的长度给出。
这两种方法都可以带来您的结果。

关于r - 在初始值之后使用先前的值对向量执行运算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35694147/

10-10 17:44
查看更多