【问题标题】:When to use a reactive expression vs to use <<- to create a global object何时使用反应式表达式与使用 <<- 创建全局对象
【发布时间】:2018-02-07 09:13:52
【问题描述】:

我正在尝试使用我同事创建的一些功能创建一个闪亮的应用程序。他经常在他的函数中使用“

问题: 1. 在这种情况下使用

这是他写的函数的一个例子:

PrepareData<-function(pickoneperday=TRUE,data) { 
  set.seed(1)
  if (pickoneperday==TRUE) {data <<- PickOnePerDay(data)} 
  data <<- RankData(data)
  SetMeasureType()
  minnodebase <<- 0.005*nrow(data)
  CodeMissingData(data)
}

【问题讨论】:

  • 你的同事为什么要这样做?这使得重用函数变得非常困难。你真的只关心这里的“更快”吗?而不是“正确的”?更完整的reproducible example
  • reactive()&lt;&lt;- 做了两件非常不同的事情。 reactive() 允许事物(例如数据框)对用户输入做出反应。 &lt;&lt;- 正如你所说的分配全局对象。它们并不是真正可以互换的。另外,我真的不明白你的同事为什么这样做。
  • 感谢您的意见。该应用程序运行速度非常慢,所以我想知道他是否使用
  • 同意其他评论者 - 你不应该采纳你同事的做法。如果您需要从函数返回对象,正确的方法是使用return(data)。否则,您只是在寻找令人困惑的错误。
  • “使用&lt;&lt;-...”:。您还可以通过让它们相互依赖来在事件之后更新多个反应值,这样每个值都可以在服务器循环中直接分配。

标签: r shiny shiny-reactivity


【解决方案1】:

首先,我认为我们需要澄清问题的范围。

  1. 如果您在 R 中编写函数,为清楚起见,最好在函数末尾使用 return() 返回值,或者至少将数据对象放在大括号之前的最后。在这种情况下,&lt;&lt;- 的使用可能会产生任何类型的错误和并发症(简而言之,这是对意大利面条编程的提醒,打破了对相关函数只有一个退出点的规则)。
  2. 不同的是shiny 特殊函数的情况。我只想提醒shiny 编码人员通常不会在闪亮函数的末尾使用return()(即使它仍然可以工作)。这里要么没有返回值,要么使用了reactive 或其他类似的构造。

部分混淆来自问题中的最小示例:示例不是shiny 特殊函数,而只是普通函数。

shiny 中,例如使用observe 之类的构造,可能会碰巧使用&lt;&lt;- 来更新全局对象。一个很好的例子(我经常回顾的一段很棒的代码)是由闪亮的开发人员之一 Jeff Allen 开发的应用程序 ShinyChat - see here on github。 在这种情况下,Jeff 使用 &lt;&lt;-observe 函数中更新在全局级别定义的 reactiveValue:非常好的风格。

我用一个小点来结束:如果你有任何函数并且你用&lt;&lt;- 更新了一个变量,并且你有一个本地定义的同名变量,那么只有全局变量被更新。 在这些情况下,您需要执行类似的操作

data <<- data <- 3

从右到左:第一个&lt;-更新了名为data的局部变量:第二个&lt;&lt;-更新了名为data的全局变量。谈论混乱。

另一方面,在闪亮的或标准的 R 中,我从来没有注意到因为 &lt;&lt;- 而变得非常缓慢,当然前提是代码中没有太多。

关于 reactivereactiveValues 等替代技术的问题,请在 SO 上查看类似问题 here 的这个很好的答案。

【讨论】:

  • 点了。我将所有&lt;&lt; 重写为&lt;&lt;-。感谢您的建议。
  • 非常感谢您的详尽解释。
猜你喜欢
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
相关资源
最近更新 更多