我正在尝试使用我的同事创建的一些功能来创建一个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)
}
答案 0 :(得分:2)
首先,我认为我们需要澄清问题的范围。
return()
返回值,或者至少将数据对象放在大括号之前。在这种情况下,<<-
的使用会产生任何类型的错误和复杂性(简而言之就是提醒意大利面条编程,打破了对所涉及功能的单一退出点的规则)。 shiny
特殊功能的情况不同。我只是想提醒一下,shiny
编码员通常不会在闪亮功能结束时使用return()
(即使它仍然有效)。这里要么没有返回值,要么使用reactive
或其他类似的结构。部分混淆来自问题中的最小示例:示例不是shiny
特殊函数,而只是普通函数。
在shiny
中,使用例如observe
之类的构造,可能会使用<<-
更新全局对象。一个很好的例子(我经常回过头来的一段很棒的代码)是Jeff Allen开发的应用程序ShinyChat,它是闪亮的开发人员之一 - see here on github。
在这种情况下,Jeff使用<<-
来更新在observe
函数内定义的全局级别的reactiveValue:非常好的样式。
我总结一点:如果你有任何函数并且用<<-
更新变量,并且你有一个在本地定义的同名变量,那么只更新全局变量。
在这些情况下,您需要执行类似
data <<- data <- 3
从右到左:第一个<-
更新了名为data
的局部变量:第二个<<-
更新了名为data
的全局变量。谈论混乱。
另一方面,在闪亮或标准的R中,由于<<-
,我从未注意到剧烈的缓慢,当然,前提是代码中没有太多。
关于reactive
或reactiveValues
等替代技术的问题,请在类似问题here上看到这个好的答案。