何时使用反应式表达式vs使用<< - 来创建全局对象

时间:2017-08-29 19:40:17

标签: r shiny shiny-reactivity

我正在尝试使用我的同事创建的一些功能来创建一个Shiny应用程序。他经常使用'<< - '运算符在他的函数中创建全局对象。

问题: 1.在这种情况下使用<< - 这是一个好习惯吗? 2.如果我使用reactive()表示对象,应用程序会更快吗? 3.有更好的建议吗?

以下是他写的函数的一个例子:

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)
}

1 个答案:

答案 0 :(得分:2)

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

  1. 如果在R中编写函数,为了清楚起见,最好使用函数末尾的return()返回值,或者至少将数据对象放在大括号之前。在这种情况下,<<-的使用会产生任何类型的错误和复杂性(简而言之就是提醒意大利面条编程,打破了对所涉及功能的单一退出点的规则)。
  2. shiny特殊功能的情况不同。我只是想提醒一下,shiny编码员通常不会在闪亮功能结束时使用return()(即使它仍然有效)。这里要么没有返回值,要么使用reactive或其他类似的结构。
  3. 部分混淆来自问题中的最小示例:示例不是shiny特殊函数,而只是普通函数。

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

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

    的操作
    data <<- data <- 3
    

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

    另一方面,在闪亮或标准的R中,由于<<-,我从未注意到剧烈的缓慢,当然,前提是代码中没有太多。

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