【问题标题】:R: Sequentially apply a function to a data frame and carry over the result to the next calcuationR:依次将函数应用于数据帧并将结果结转到下一次计算
【发布时间】:2013-08-28 07:48:19
【问题描述】:

我正在研究一些动态问题(关于使用贝叶斯规则更新信念)并寻求“无循环”解决方案来加快计算速度,因为我当前使用 for 循环的解决方案非常慢。

假设我有一个数据框或矩阵,对于每一行,我都想做同样的计算。但是,r 行的计算需要在前面的r-1 行计算中生成的输出。该过程可以通过以下方式说明:

假设我有一个R by n 矩阵、MA 和一些初始变量y0

  1. [input] MA[1,] + y0 => [output] y1
  2. [input] MA[2,] + y1 => [output] y2
  3. [input] MA[3,] + y2 => [output] y3
  4. ....

最简单的例子之一可能是n! 的计算。 n! = n * (n-1)! 的值,其中(n-1)! 是前面计算的结果。

我想出的第一个函数是apply 系列,但应用函数不能像我现在这样应用于递归(或动态)操作;它只是对不同的输入重复相同的计算,但不会向前传递输出。不确定我们是否可以使用任何其他技巧。任何天才都可以为这个特定问题提出一个无循环的解决方案吗?

【问题讨论】:

  • 请提供一些示例输入数据和预期输出。几行应该没问题。您还应该从 base R 中探索within
  • 您的循环很慢可能是因为您不断地复制。阅读 Patrick Burns 的 burns-stat.com/pages/Tutor/R_inferno.pdf,您会受益匪浅。

标签: r apply


【解决方案1】:

这不应该更快,可能更慢,但他是我避免 for 循环的尝试:

# input data
MA <- matrix(1:8, nrow=4)
y0 <- 1

# compute
l <- Reduce(function(x, y) MA[y,] + x, seq_len(nrow(MA)), init=y0, accumulate=TRUE)

# format
res2 <- data.matrix(t(as.data.frame(l[-1])))
rownames(res2) <- NULL

【讨论】:

    【解决方案2】:

    您可以将数据存储在函数中。一个例子!

    df <- data.frame(r = 1:10)
    
    parent.iteration <- function() {
      i <- 0
      n <- 1
      function() {
        i <<- i + 1
        n <<- n * i
        n
      }
    }
    
    # create closure
    child.iteration <- parent.iteration()
    df$result <- apply(df,1,function(x)child.iteration())
    
    # continues where it left off
    df$result2 <- apply(df,1,function(x)child.iteration())
    df
    

    更多信息:Closures

    【讨论】:

      【解决方案3】:

      以下应该适用于 apply 系列函数......但这些也包含循环。您也许可以使用 mclappy() 加快操作速度

      ne <- new.env() # create a new environment
      ne$ystore <- y0 # create an object to store the output value and initialize at y0
      
      calc.rec <- function(x) ne$ystore <- MA[x, ] + ne$ystore
      sapply(1:nrow(MA), calc.rec)
      

      如果这太慢了,根据您要执行的确切计算类型,您可以使用 cumsum()、cumprod() 等来对它们进行矢量化。

      【讨论】:

        猜你喜欢
        • 2013-03-28
        • 2014-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多