2017-08-29 33 views
0

我正尝试使用我的同事创建的一些函数创建Shiny应用程序。他经常在他的函数中使用'< <'运算符来创建全局对象。何时使用反应表达式vs使用<< - 创建全局对象

问题: 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) 
} 
+2

为什么你的同事这样做?它使得重用功能非常困难。你真的只关心“更快”吗?而不是“正确”?一个更完整的[可重现的例子](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)。 – MrFlick

+4

'reactive()'和'<< - '做了两件完全不同的事情。 'reactive()'允许一个东西(例如数据框)对用户输入做出反应。如你所说的,<< << - 分配全局对象。它们并非真正可以互换。另外,我不明白你的同事为什么这样做。 –

+0

感谢您的输入。该应用程序运行速度慢,所以我不知道他是否使用“解释缓慢。看起来更好的做法是重写函数(避免使用<<)而不是使用reactive()。任何其他建议,欢迎和赞赏。 – Ketty

回答

2

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

  1. 如果你写R中的功能,这是很好的做法无论使用return()在函数结束时,为清楚起见,或至少把数据对象的大括号前的最后一次返回的值。在这种情况下,使用<<-可以产生任何类型的错误和复杂性(简而言之,是提醒意大利面条编程,打破有关单一出口点的规则)。
  2. shiny特殊功能的情况不同。我只是想提醒shiny编码器通常不会在有光泽的功能结束时使用return()(即使它仍能正常工作)。这里要么没有返回价值,要么使用reactive或其他类似的结构。

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

shiny中,使用例如像observe这样的结构,可能碰巧使用<<-来更新全局对象。一个非常好的例子(我经常回顾的一段很棒的代码)是杰夫艾伦开发的应用ShinyChat,闪亮开发者之一 - see here on github。 在这种情况下,Jeff使用<<-来更新在observe函数中在全局级定义的reactiveValue:非常好的样式。

我以一个小点来结束:如果您有任何功能,并且您使用<<-更新变量,并且您有一个本地定义的同名变量,则只会更新全局变量。 在这种情况下,你需要做的是这样

data <<- data <- 3 

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

另一方面,在有光泽或标准的R中,我从来没有注意到由于<<-而导致的极度缓慢,当然规定代码中没有太多。

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

+0

拿了点。我将所有'<<'重写为'<< - '。感谢您的建议。 – Enzo

+0

非常感谢您的详细解释。 – Ketty

相关问题