对于 Shiny 中反应函数内的循环

For loop inside reactive function in Shiny

我在 Shiny 服务器中遇到了 for 循环的问题,直到现在还没有人知道如何修复它。我已经为此工作了好几天,但仍然没有取得任何进展。长话短说,请看下面的代码。我试图从 Google Finance 获取数据并计算平滑方差。

  stock2 <-
    reactive(
      getSymbols(
        toupper(input$ticker2),
        from = as.Date(input$date2[1]) - 150,
        to = input$date2[2],
        src = "google",
        auto.assign = F
      )
    )

  stock3 <- reactive(as.data.table(stock2()))
  stock <- reactive(as.data.frame(stock3()))
  stock.return <- reactive(diff(log(stock()[, 5])))
  stock.mu <- reactive(mean(stock.return()))
  stock.var <- reactive((stock.return() - stock.mu()) ^ 2)
  stock.var.smoothed <- reactive(rep(0, length(stock.return())))

上面的代码工作得很好,我已经测试过了。

所以问题是下面的代码,我想根据一些计算来分配一个向量,但我不知道正确的方法。

  stock.var.smoothed <- reactive({
    for (i in 2:length(stock.var())) {
      stock.var.smoothed[1] <<- stock.var()[1]
      stock.var.smoothed[i] <<-
        (1 - input$alpha) * stock.var.smoothed()[i - 1] + input$alpha * stock.var()[i]
    }
  })

for 循环根本不起作用。 错误代码是

错误:'closure' 类型的对象不是子集

但是我已经使用 () 作为函数内部的变量。所以我不知道如何解决这个问题。

顺便说一句,我也试过下面的代码

for (i in 2:length(stock.return())) {
  stock.momentum.smoothed[1] <- reactive(stock.momentum()[1])
  stock.momentum.smoothed[i] <-
    reactive((1 - input$beta) * stock.momentum.smoothed()[i - 1] + input$beta * stock.return()[i])
}

错误代码是

没有活动的反应上下文不允许操作。 (你试图做一些只能从反应式表达式或观察者内部完成的事情。)

感谢任何能提供帮助的人。谢谢!

您对反应式 (stock.var.smoothed[1] <<-) 的子集分配根本没有意义:此操作不会是您想要的,即使没有子集化(它会用非-替换您的反应式对象)反应值;即它将停止反应)。

可以在反应式表达式中创建和分配变量。但不要分配给全局环境(即不要使用 <<-),也不要尝试重新分配反应对象本身。相反,创建一个本地临时变量:

stock.var.smoothed <- reactive({
  value <- numeric(length(stock.var()))
  value[1] <- stock.var()[1]

  for (i in 2 : length(stock.var())) {
    value[i] <- (1 - input$alpha) * value[i - 1] + input$alpha * stock.var()[i]
  }

  value
})

在这里,value 可以是任何名称(包括 stock.var.smoothed — 但这将是一个 与您的反应变量不同的 变量,因为它在不同的环境中范围)。

此外,我很确定这段代码是在没有循环和临时变量的情况下编写的(但在我看来它会是什么样子并不是很明显)。

最后,关于代码风格的注意事项:不要在变量名中使用 .。这很令人困惑,因为它也用于 S3 分派以分隔方法的通用名称和 class 名称。 R 中的一个常见约定是使用下划线代替 (stock_var_smoothed).