ShinyeventReactiveハンドラー内で複数のイベント式をリッスンする方法


85

アプリのさまざまなプロット/出力で使用されているデータの更新をトリガーする2つの異なるイベントが必要です。1つはクリックされているボタン(input$spec_button)で、もう1つはクリックされているドット上の点(mainplot.click$click)です。

基本的には両方を同時にリストしたいのですが、コードの書き方がわかりません。これが私が今持っているものです:

server.Rで:

data <- eventReactive({mainplot.click$click | input$spec_button}, {
    if(input$spec_button){
      # get data relevant to the button
    } else {
      # get data relevant to the point clicked
    }
  })

しかし、if-else句は機能しません

Error in mainplot.click$click | input$spec_button : operations are possible only for numeric, logical or complex types

->mainplot.click$click | input$spec_button句に使用できるアクションコンバイナー関数のようなものはありますか?


!is.null(input $ spec_button)の出力を確認できますか?
ゴパラ2016年

回答:


94

これは古いことは知っていますが、同じ質問がありました。私はついにそれを理解しました。中かっこで式を含め、イベント/リアクティブオブジェクトをリストするだけです。私の(根拠のない)推測では、shinyは、この式ブロックに対して、標準reactiveブロックと同じリアクティブポインター分析を実行するだけです。

observeEvent({ 
  input$spec_button
  mainplot.click$click
  1
}, { ... } )

編集

式の最後の行がNULLを返す場合を処理するように更新されました。定数値を返すだけです。


1
これは私の元の解決策よりも優れた解決策のように思われるので、受け入れられた答えをこれに変更します。
ヒラリーサンダース

3
どのイベントがトリガーされたかを特定できますか?
PeterVermont 2017年

私が知っていることではありません。いくつかのケースでは、それらを別々の変数で追跡し、自分で比較してどちらが変更されたかを確認しました。しかし、それは醜いです。おそらく、メインコードを関数に配置し、fnを呼び出す2つのobserveEventを作成してから、各イベントに対して特定の処理を実行する方がよいでしょう。
ダンカンブラウン

8
警告:デフォルトでobserveEvent使用ignoreNULL = TRUEします。つまり、mainplot.click$click(戻り値)がの場合、変更されてもNULLハンドラーは呼び出されませinput$spec_button。この罠に陥らないように、@ JustAnotherの回答のようなものをお勧めします。
greg L

1
別の警告:私のテストでは、この{}角かっこ構文()では、各イベントが独自の改行である必要があることがわかりました。そうでない場合、パーサーが2番目のイベントを検出するとすぐに「Errorinparse ...」で失敗します。たとえば、すべて1行で:observeEvent({input$spec_button mainplot.click$click}, {...})失敗します。S3 Generic結合構文(c())を使用した@JustAnotherの回答は、改行に関係なく機能します。
ブライアンD

54

また:

observeEvent(c( 
  input$spec_button,
  mainplot.click$click
), { ... } )

6
これは@DuncanBrownの回答と非常によく似ていますが、2つのアクションボタンの両方がモーダルをトリガーする状況を見つけました。これは機能し、{バージョンは機能しませんでした。なぜそうなのか説明できません。
ジョンポール

2
@Duncan Brownの回答に、この回答の違い(およびより良いIMO)に関するコメントを追加しました
greg L

これは私には機能しません-エラーが発生します(光沢のある1.0.5)
potockan 2018年

どのイベントがトリガーされたかを確認する方法はありますか?2つのボタンがinput$button1ありinput$button2、インデックスが異なるだけで、非常によく似た処理を実行するとします。インデックスがわからないという理由だけで、コードを何度もコピーすることは避けたいと思います。ありがとう!
Nikos Bosse

10

リアクティブオブジェクトを作成し、それをイベント変更式で使用することで、この問題を解決しました。以下のように:

xxchange <- reactive({
paste(input$filter , input$term)
})

output$mypotput <- eventReactive( xxchange(), {
...
...
...
} )

4
これは非常に良い答えであり、より多くの説明から利益を得ることができます。受け入れられた回答はより単純で、初歩的なプログラムに適していますが、この回答は大規模で複雑なコードに適しています。答えから2つのポイントが欠落しているようです(1)貼り付け(またはリスト)は、2つのイベントを同じ行に配置して、コードをよりコンパクトにします。(2)リアクティブオブジェクトは、複数のリスナーが同じイベントセットをリッスンしている場合に、同じ2つのイベントを何度も繰り返す手間を省きます。
農業

5

私が思いついた解決策は次のとおりです。基本的に、空のreactiveValuesデータホルダーを作成し、2つの別々のobserveEventインスタンスに基づいてその値を変更します。

  data <- reactiveValues()
  observeEvent(input$spec_button, {
    data$data <- get.focus.spec(input=input, premise=premise, 
                                itemname=input$dropdown.itemname, spec.info=spec.info)
  })
  observeEvent(mainplot.click$click, {
    data$data <- get.focus.spec(input=input, premise=premise, mainplot=mainplot(),
                                mainplot.click_focus=mainplot.click_focus(),
                                spec.info=spec.info)  
  })

3
list(mainplot.click$click, input$spec_button)もOPの道のために働きます。
ジョン

1

これは、アクションをベクターに入れるだけで、eventReactiveを使用して実行できます。

eventReactive(
  c(input$spec_button, mainplot.click$click), 
{ ... } )

0

ここでの考え方は、observeEventで渡したい条件を実行するリアクティブ関数を作成し、このリアクティブ関数を渡してステートメントの有効性を確認することです。例えば:

validate_event <- reactive({
    # I have used OR condition here, you can use AND also
    req(input$spec_button) || req(mainplot.click$click)
})

observeEvent(validate_event(), 
    { ... } 
)

コーディングを続けてください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.