【问题标题】:For loop inside reactive function in Shiny闪亮的反应函数内的循环
【发布时间】:2018-02-17 11:30:54
【问题描述】:

我在 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 循环根本不起作用。 错误代码是

错误:“闭包”类型的对象不是子集

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

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

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 是一个“反应式”对象。换句话说,它是一个函数,正如 R 所说,你不能对它进行子集化。您需要调用它,然后然后子集化结果。
  • 感谢您的回复。你能告诉我怎么称呼它吗?我完全空白..
  • 或者说我如何在 Shiny 中为向量编写一个 for 循环?
  • 如果不仔细观察,我肯定会将stock.var 的结果分配给一个临时向量,并在您的响应式中使用它。更高效,更容易阅读,出错的可能性更少。
  • 谢谢迈克。但是我们怎么能做到呢?看来我们只能在reactive() 函数中分配一个向量。那么有什么区别呢?

标签: r loops vector shiny reactive


【解决方案1】:

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

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

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 调度以分隔方法的通用名称和类名称。 R 中的一个常见约定是使用下划线 (stock_var_smoothed)。

【讨论】:

  • 非常感谢!它奏效了,你的解释很清楚!
猜你喜欢
  • 2016-07-17
  • 2013-07-16
  • 2021-06-09
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多