2016-11-25 4 views
7

ここで何かに悩まされていて光栄ですが、基本的なことはよく知っています。そのポイントを強調表示するためにポイントをクリックしたときに、ggplotレイヤーを追加したいと考えています。私はこれがggvisで可能であることを知っています。ギャラリーには素晴らしい例がありますが、nearPoints()を使用してクリックをUI入力として取得したいと考えています。動的なggplotレイヤーが光沢のあるnearPoints()

私はggplotレイヤーとは別に動作するものを試してみました(下記参照)。私はreactive()eventReactive()などですべての種類の編集を試しました。

すべてのヘルプははるかに高く評価されています...

library(shiny) 
library(ggplot2) 

shinyApp(
    ui = shinyUI(
     plotOutput("plot", click = "clicked") 
    ), 

    server = shinyServer(function(input, output) { 
    output$plot <- renderPlot({ 
     ggplot(mtcars, aes(x = mpg, y = wt)) + 
     geom_point() + 
     geom_point(data = nearPoints(mtcars, input$clicked), colour = "red", size = 5) 
    }) 
    }) 
) 

私はこれが動作しない理由を私は概念的に理解だと思います。プロットはinput$clickedに依存しています。つまり、input$clickedが変更されるとプロットが再描画されますが、これは次にinput$clickedをリセットします。キャッチ22の状況のビット。

答えて

8

、これを試してください:あなたは、それが強調表示されているポイントを一度クリックした場合

アプローチ1を

library(shiny) 
library(ggplot2) 

# initialize global variable to record selected (clicked) rows 
selected_points <- mtcars[0, ] 
str(selected_points) 


shinyApp(
    ui = shinyUI(
    plotOutput("plot", click = "clicked") 
), 

    server = shinyServer(function(input, output) { 

    selected <- reactive({ 
     # add clicked 
     selected_points <<- rbind(selected_points, nearPoints(mtcars, input$clicked)) 
     # remove _all_ duplicates if any (toggle mode) 
     # http://stackoverflow.com/a/13763299/3817004 
     selected_points <<- 
     selected_points[!(duplicated(selected_points) | 
          duplicated(selected_points, fromLast = TRUE)), ] 
     str(selected_points) 
     return(selected_points) 
    }) 

    output$plot <- renderPlot({ 
     ggplot(mtcars, aes(x = mpg, y = wt)) + 
     geom_point() + 
     geom_point(data = selected(), colour = "red", size = 5) 
    }) 
    }) 
) 

(推奨)。それをもう一度クリックすると、ハイライトが再びオフになります(トグル)。

コードでは、グローバル変数selected_pointsを使用して、実際にハイライトされた(選択された)ポイントと、ポイントがクリックされるたびにグローバル変数を更新する反応式selected()を保存します。

str(selected_points)は、作業をビジュアル化するのに役立ちますが、削除することができます。

アプローチ2(代替)

observe()

は、代わりのreactive()及び参照グローバル変数selected_points直接代わりに関数からオブジェクトを返すを使用して、わずかに異なるアプローチがある:もちろん

library(shiny) 
library(ggplot2) 

selected_points <- mtcars[0, ] 
str(selected_points) 


shinyApp(
    ui = shinyUI(
    plotOutput("plot", click = "clicked") 
), 

    server = shinyServer(function(input, output) { 

    observe({ 
     # add clicked 
     selected_points <<- rbind(selected_points, nearPoints(mtcars, input$clicked)) 
     # remove _all_ duplicates (toggle) 
     # http://stackoverflow.com/a/13763299/3817004 
     selected_points <<- 
     selected_points[!(duplicated(selected_points) | 
          duplicated(selected_points, fromLast = TRUE)), ] 
     str(selected_points) 
    }) 

    output$plot <- renderPlot({ 
     # next statement is required for reactivity 
     input$clicked 
     ggplot(mtcars, aes(x = mpg, y = wt)) + 
     geom_point() + 
     geom_point(data = selected_points, colour = "red", size = 5) 
    }) 
    }) 
) 

リアクティブ関数selected()を呼び出す代わりに、グローバル変数selected_pointsggplot呼び出しで直接使用することができます。ただし、input$clickedが変更されるたびにrenderPlot()が実行されるようにする必要があります。したがって、renderPlot()のコードには、input$clickedへのダミー参照をコードに含める必要があります。

ここで、リアクティブ関数selected()は不要になり、observe()式で置き換えることができます。 reactive()とは対照的に、observe()は値を返しません。 input$clickedが変更されるたびに、グローバル変数selected_pointsが更新されます。

アプローチ3(無効な値)

このアプローチでは、グローバル変数が回避されます。代わりにreactiveValuesを使用して、リアクティブプログラミング(?reactiveValuesを参照)のための特別な機能を持つリスト様オブジェクトrvを作成します。

library(shiny) 
library(ggplot2) 

shinyApp(
    ui = shinyUI(
    plotOutput("plot", click = "clicked") 
), 

    server = shinyServer(function(input, output) { 

    rv <- reactiveValues(selected_points = mtcars[0, ]) 

    observe({ 
     # add clicked 
     rv$selected_points <- rbind(isolate(rv$selected_points), 
              nearPoints(mtcars, input$clicked)) 
     # remove _all_ duplicates (toggle) 
     # http://stackoverflow.com/a/13763299/3817004 
     rv$selected_points <- isolate(
     rv$selected_points[!(duplicated(rv$selected_points) | 
           duplicated(rv$selected_points, fromLast = TRUE)), ]) 
     str(rv$selected_points) 
    }) 

    output$plot <- renderPlot({ 
     ggplot(mtcars, aes(x = mpg, y = wt)) + 
     geom_point() + 
     geom_point(data = rv$selected_points, colour = "red", size = 5) 
    }) 
    }) 
) 

は、 input$clickedへの変更のみが observerでコードの実行をトリガーすることを保証するために isolate()にカプセル化する必要が rvから observerパーツ参照であることに注意してください。それ以外の場合は、無限ループになります。無効値 rvが変更されると、実行は renderPlotになります。

結論

は個人的には、依存性(反応性)がより明確する反応性官能基を使用したアプローチ1を好みます。アプローチ2でクリックされた$を入力するダミーコールは直感的ではありません。アプローチ3では、反応性の徹底的な理解と適切な場所でのisolate()の使用が必要です。

+0

ありがとうございます。最初はなぜ2番目の 'geom_point'レイヤーにデータソース' selected() 'があるのか​​理解できませんでしたが、' selected() '関数が' selected_points'オブジェクトを返すことが分かりました。興味のない、私はデータソースとして 'selected_points'を持っていて、関数からオブジェクトを返すことはできませんか?もしそうなら、なぜあなたは他のものよりもこのようにしますか? – roman

+1

特定のデータが変更されたとき(反応性)、反応性に関するコードや実行されるコードはどれですか?はい、 'selected_points'を使うことができますが、' input $ clicked'にダミーの呼び出しを加えることで反応性を強制する必要があります(私の編集した回答の_Approach 2_を参照)。依存関係をより明示的にするリアクティブ関数を使用する方が好きです。 – Uwe

+0

拡張回答ありがとう - 非常に役に立ちます。 – roman

関連する問題