2017-08-29 59 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

相關問題