R shiny教程-6:使用響應(yīng)表達(dá)式reactive()

stockVis app

Shiny apps構(gòu)建好之后矿酵,其運(yùn)行與反應(yīng)要快速才會(huì)吸引用戶全肮;因此棘捣,在構(gòu)建Shiny apps時(shí),耗時(shí)計(jì)算代碼的放置顯得尤為重要评疗。

#例子 - stockVis

##創(chuàng)建stockVis Shiny app

  • 創(chuàng)文件夾:stockVis
  • 下載: app.Rhelpers.R
  • 安裝quantmod包:install.packages("quantmod")
  • 運(yùn)行:runApp("stockVis")
stockVis app

stockVis應(yīng)用程序根據(jù)股票代碼查找股票價(jià)格茵烈,并將結(jié)果顯示為折線圖。

  • 選擇要檢查的股票
  • 選擇一系列要回顧的日期
  • 選擇是否在y軸上繪制股票價(jià)格或股票價(jià)格的對數(shù)加匈,
  • 決定是否根據(jù)通貨膨脹調(diào)整價(jià)格仑荐。

注:注意,“為通貨膨脹調(diào)整價(jià)格”復(fù)選框還不能工作粘招。本節(jié)的任務(wù)之一是修復(fù)這個(gè)復(fù)選框。

默認(rèn)情況下示姿,stockVis會(huì)顯示SPY代碼(整個(gè)標(biāo)普500的一個(gè)指數(shù))逊笆。要查找不同的股票,請鍵入雅虎財(cái)經(jīng)能夠識別的股票符號难裆。你可以在這里查看雅虎的股票代碼:here。一些常見的符號是GOOG(谷歌)褂痰、AAPL (Apple)和GS (Goldman Sachs)症虑。

stockVis非常依賴quantmod包中的兩個(gè)功能:

  • 使用getsymbols直接從雅虎財(cái)經(jīng)(Yahoo finance)和圣路易斯聯(lián)邦儲(chǔ)備銀行(Federal Reserve Bank of St. Louis)等網(wǎng)站下載金融數(shù)據(jù)。
  • 使用chartSeries在一個(gè)吸引人的圖表中顯示價(jià)格谍憔。
  • stockVis還依賴于一個(gè)名為helpers.R腳本主籍。它包含一個(gè)根據(jù)通貨膨脹調(diào)整股票價(jià)格的函數(shù)千元。

#復(fù)選框和日期范圍

stockVis應(yīng)用程序使用了一些新的小部件:

  • 日期范圍選擇器颤绕,使用dateRangeInput
  • 用checkboxInput創(chuàng)建的幾個(gè)復(fù)選框。復(fù)選框小部件非常簡單奥务。當(dāng)復(fù)選框被選中時(shí),它們返回TRUE议纯,當(dāng)復(fù)選框未被選中時(shí)返回FALSE溢谤。
  • 這些復(fù)選框在ui對象中被命名為log和adjust,這意味著您可以在服務(wù)器函數(shù)中將它們作為inputlog和inputadjust進(jìn)行查找阀参。

#簡化計(jì)算

檢查當(dāng)您點(diǎn)擊“在對數(shù)尺度上繪制y軸”時(shí)會(huì)發(fā)生什么。input$log的值會(huì)改變蛛壳,這會(huì)導(dǎo)致renderPlot中的整個(gè)表達(dá)式重新運(yùn)行:

output$plot <- renderPlot({
  data <- getSymbols(input$symb, src = "yahoo",
                     from = input$dates[1],
                     to = input$dates[2],
                     auto.assign = FALSE)

  chartSeries(data, theme = chartTheme("white"),
              type = "line", log.scale = input$log, TA = NULL)
})

當(dāng)renderPlot重新運(yùn)行時(shí):

  • 它使用getSymbols從Yahoo finance重新獲取數(shù)據(jù)
  • 它重新繪制圖表所刀。

這并不好,因?yàn)槟恍枰匦芦@取數(shù)據(jù)來重新繪制繪圖忧吟。事實(shí)上斩披,如果你過于頻繁地重新獲取數(shù)據(jù),雅虎財(cái)經(jīng)(Yahoo finance)會(huì)切斷你的服務(wù)(因?yàn)槟汩_始看起來像個(gè)爬蟲機(jī)器人)垦沉。但更重要的是,重新運(yùn)行g(shù)etSymbols是不必要的工作寡壮,這會(huì)降低應(yīng)用程序的速度并消耗服務(wù)器。

#響應(yīng)表達(dá)式

可以限制在使用反應(yīng)表達(dá)式的反應(yīng)期間重新運(yùn)行的內(nèi)容诬像。
使用reactive函數(shù)創(chuàng)建一個(gè)響應(yīng)表達(dá)式,就像渲染render*函數(shù)。
例如,下面是一個(gè)反應(yīng)式表達(dá)式邪乍,它使用stockVis的小部件從Yahoo獲取數(shù)據(jù)。

dataInput <- reactive({
  getSymbols(input$symb, src = "yahoo",
    from = input$dates[1],
    to = input$dates[2],
    auto.assign = FALSE)
})

當(dāng)您運(yùn)行表達(dá)式時(shí)榜配,它將運(yùn)行g(shù)etSymbols并返回結(jié)果。您可以通過調(diào)用dataInput()在renderPlot中使用價(jià)格數(shù)據(jù)蛋褥。

output$plot <- renderPlot({    
  chartSeries(dataInput(), theme = chartTheme("white"),
    type = "line", log.scale = input$log, TA = NULL)
})

響應(yīng)表達(dá)式比常規(guī)R函數(shù)更聰明一些睛驳。它們緩存數(shù)據(jù)。并知道它們的值何時(shí)已經(jīng)更新淫茵。

第一次運(yùn)行反應(yīng)表達(dá)式時(shí),該表達(dá)式將其結(jié)果保存在計(jì)算機(jī)的內(nèi)存中匙瘪。下一次調(diào)用響應(yīng)表達(dá)式時(shí)蝶缀,它可以返回這個(gè)保存的結(jié)果,而不進(jìn)行任何計(jì)算(這會(huì)使應(yīng)用程序更快)翁都。

反應(yīng)表達(dá)式只有在知道結(jié)果是最新的情況下才會(huì)返回保存的結(jié)果。如果反應(yīng)表達(dá)式獲悉結(jié)果已經(jīng)更新了(因?yàn)楦淖兞诵〔考?,表達(dá)式將重新計(jì)算結(jié)果骑冗。然后返回新的結(jié)果并保存一個(gè)新的副本先煎。反應(yīng)表達(dá)式將使用這個(gè)新的副本,直到它也更新為止薯蝎。

reactive()優(yōu)勢:

  • 反應(yīng)式表達(dá)式在第一次運(yùn)行時(shí)保存其結(jié)果。
  • 下一次調(diào)用響應(yīng)表達(dá)式時(shí)袒哥,它檢查保存的值是否已更新(即,它所依賴的小部件是否已更改)堡称。
  • 值沒更新,就可以調(diào)用先前保存的值桐臊,不進(jìn)行任何計(jì)算晓殊;更新了的話,重新運(yùn)算表達(dá)式計(jì)算結(jié)果巫俺。

可以用reactive()來防止Shiny重新運(yùn)行不必要的代碼∪次耍考慮一下反應(yīng)表達(dá)式將如何在下面的新stockVis應(yīng)用程序中工作。

server <- function(input, output) {

  dataInput <- reactive({
    getSymbols(input$symb, src = "yahoo",
               from = input$dates[1],
               to = input$dates[2],
               auto.assign = FALSE)
  })

  output$plot <- renderPlot({

    chartSeries(dataInput(), theme = chartTheme("white"),
                type = "line", log.scale = input$log, TA = NULL)
  })

}

當(dāng)你點(diǎn)擊“Plot y axis on the log scale”稽穆,輸入input$log將改變赶撰,renderPlot將重新執(zhí)行。

  • renderPlot將調(diào)用dataInput()
  • dataInput將檢查dates和symb小部件是否沒有更改
  • dataInput將返回其保存的股票價(jià)格數(shù)據(jù)集餐胀,而無需重新從雅虎獲取數(shù)據(jù)
  • renderPlot將用選擇的的軸表達(dá)方式重新繪制圖表。

#依賴性

當(dāng)在Shiny app修改了股票代碼否灾,Shiny 也會(huì)知道鸣奔,并且重新畫圖。

當(dāng)遇到以下兩種情況挎狸,Shiny會(huì)重新運(yùn)行:

  • 對象的render*函數(shù)中的input中的值發(fā)生變化,
  • 對象的render*函數(shù)中的反應(yīng)性表達(dá)式已經(jīng)更新

可以將反應(yīng)表達(dá)式看作連接崭别,鏈接input和output中的對象。output中的對象將響應(yīng)鏈中任何下游所做的更新舞痰。(可以設(shè)計(jì)一個(gè)長鏈,因?yàn)榉磻?yīng)表達(dá)式可以調(diào)用其他反應(yīng)表達(dá)式)

#修復(fù) “Adjust prices for inflation”

現(xiàn)在來修復(fù) “Adjust prices for inflation”响牛,用戶就能夠根據(jù)通貨膨脹調(diào)整的價(jià)格和未調(diào)整的價(jià)格之間切換赫段。

server <- function(input, output) {

  dataInput <- reactive({
    getSymbols(input$symb, src = "yahoo",
        from = input$dates[1],
        to = input$dates[2],
        auto.assign = FALSE)
  })

  output$plot <- renderPlot({   
    data <- dataInput()
    if (input$adjust) data <- adjust(dataInput())

    chartSeries(data, theme = chartTheme("white"),
        type = "line", log.scale = input$log, TA = NULL)
  })
}

#總結(jié)

通過使用reactive()模塊化代碼,可以加快應(yīng)用程序的速度.

  • reactive()接受輸入值或其他反應(yīng)表達(dá)式的值,并返回一個(gè)新值
  • reactive()保存它們的結(jié)果坯台,并且只會(huì)在輸入發(fā)生更改時(shí)重新計(jì)算
  • 使用reactive({ })創(chuàng)建響應(yīng)表達(dá)式
  • 調(diào)用reactive()結(jié)果,使用reactive expressions名稱加括號
    • dataInput <- reactive({})的結(jié)果調(diào)用方法是dataInput();dataInput() 中有多個(gè)對象時(shí)蜒蕾,使用dataInput()$對象名調(diào)用
  • 只有在reactive()render* 中可以使用reactive()

#原文:

Use reactive expressions

系列文章:
R shiny教程-1:一個(gè) Shiny app的基本組成部分
R shiny教程-2:布局用戶界面
R shiny教程-3:添加小部件到Shiny App
R shiny教程-4:Shiny app響應(yīng)式結(jié)果展示
R shiny教程-5:調(diào)用R程序和導(dǎo)入數(shù)據(jù)
Shiny Server安裝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咪啡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子毅桃,更是在濱河造成了極大的恐慌,老刑警劉巖钥飞,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衫嵌,死亡現(xiàn)場離奇詭異,居然都是意外死亡楔绞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門桦锄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耻讽,“玉大人,你說我怎么就攤上這事∠惆椋” “怎么了具则?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長低斋。 經(jīng)常有香客問我,道長膊畴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任唇跨,我火速辦了婚禮衬衬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玉控。我一直安慰自己,他們只是感情好高诺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布讽挟。 她就那樣靜靜地躺著,像睡著了一般耽梅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诅迷,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天众旗,我揣著相機(jī)與錄音,去河邊找鬼贡歧。 笑死赋秀,一個(gè)胖子當(dāng)著我的面吹牛律想,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播技即,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼身笤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起液荸,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤脱篙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后涡尘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡考抄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年蔗彤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片然遏。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖丢早,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情怨酝,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布农猬,位于F島的核電站售淡,受9級特大地震影響慷垮,放射性物質(zhì)發(fā)生泄漏揍堕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一鹤啡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧递瑰,春花似錦、人聲如沸抖部。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至傲宜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間函卒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工报嵌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熊榛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓血筑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親煎楣。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355