Bir Shiny olayında birden fazla olay ifadesi nasıl dinlenir?


88

İki farklı olayın uygulamamdaki çeşitli grafikler / çıktılar tarafından kullanılan verilerin bir güncellemesini tetiklemesini istiyorum. Biri tıklanan bir düğmedir ( input$spec_button) ve diğeri tıklanan nokta üzerindeki bir noktadır ( mainplot.click$click).

Temel olarak, her ikisini de aynı anda listelemek istiyorum, ancak kodu nasıl yazacağımdan emin değilim. İşte şimdi sahip olduğum şey:

sunucuda.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
    }
  })

Ama if-else cümlesi çalışmıyor

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

-> Cümle için kullanabileceğim bir tür eylem birleştirici işlevi var mainplot.click$click | input$spec_buttonmı?


! İs.null (input $ spec_button) çıktısını kontrol edebilir misiniz?
Gopala

Yanıtlar:


97

Bunun eski olduğunu biliyorum, ama aynı sorum vardı. Sonunda anladım. Parantez içine bir ifade eklersiniz ve yalnızca olayları / reaktif nesneleri listelersiniz. Benim (kanıtlanmamış) tahminim, Bright'ın basitçe, bu ifade bloğuna standart bir reactivebloğa göre aynı reaktif işaretçi analizini gerçekleştirmesidir .

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

DÜZENLE

İfadedeki son satırın NULL döndürdüğü durumu işlemek için güncellendi. Sabit bir değer döndürmeniz yeterlidir.


1
Benim orijinal çözümümden daha iyi bir çözüm gibi göründüğü için buna kabul edilen cevabı değiştirmek.
Hillary Sanders

3
Hangi olayın tetiklendiğini belirleyebilir misiniz?
PeterVermont

Farkında olduğumdan değil. Bunu birkaç durumda, onları ayrı değişkenlerde takip ederek ve hangisinin değiştiğini görmek için karşılaştırmayı kendim yaparak yaptım. Ama bu çirkin. Muhtemelen ana kodu bir işleve koymak, sonra fn'yi çağıran ve her olay için belirli şeyler yapan iki observeEvent'e sahip olmak daha iyidir.
Duncan Brown

8
Yalnızca bir uyarı: varsayılan olarak observeEventkullanır ignoreNULL = TRUE, yani mainplot.click$click(dönüş değeri) ise NULL, işleyici değiştirilse bile asla çağrılmayacaktır input$spec_button. Bu tuzağa düşmeyi önlemek için @ JustAnother'ın cevabı gibi bir şey tavsiye ederim.
greg L

1
Başka bir uyarı: Testlerimde, bu köşeli parantez sözdiziminin ( {}) her olayın kendi satırsonu satırında olmasını GEREKTİRDİĞİNİ, aksi takdirde ayrıştırıcı ikinci olayla karşılaştığı anda "Ayrıştırmada hata ..." ile başarısız olduğunu buldum . örneğin, tümü tek satırda: observeEvent({input$spec_button mainplot.click$click}, {...})başarısız. @ JustAnother'ın S3 Generic kombine sözdizimini ( c()) kullanarak cevabı satırsonu satırlarından bağımsız olarak çalışır.
Brian D

57

Ayrıca:

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

6
Bu, @DuncanBrown'ın cevabına çok benzemekle birlikte, 2 eylem düğmesinin hem bir modal tetiklediği, bunun işe yaradığı ve {sürümün çalışmadığı bir durum buldum . Bunun neden böyle olduğunu açıklayamam.
John Paul

2
@Duncan Brown'un bu cevabın nasıl farklı (ve daha iyi IMO) olduğuna dair cevabına bir yorum eklendi
greg L

Bu benim için çalışmıyor - Bir hata alıyorum (parlak 1.0.5)
potockan

Hangi olayın tetiklendiğini bulmanın bir yolu var mı? diyelim ki benim iki düğmem var input$button1ve input$button2bu çok benzer şeyler yapıyor, sadece farklı bir indeksle. Dizini bilmediğim için kodu birden çok kez kopyalamaktan kaçınmak istiyorum. Teşekkürler!
Nikos Bosse

11

Bu sorunu reaktif bir nesne oluşturarak çözdüm ve olay değişikliği ifadesinde kullandım. Aşağıdaki gibi:

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

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

5
Bu, daha fazla açıklamadan yararlanabilecek çok iyi bir cevaptır. Kabul edilen cevap daha basittir ve ilkel programlar için daha iyi olurken, bu cevap büyük ve karmaşık kodlar için daha uygundur. Cevapta iki nokta eksik görünüyor (1) Yapıştır (veya liste), iki olayı aynı satıra koyar ve kodu daha kompakt hale getirir. (2) Reaktif nesne, aynı olay kümesini birden fazla dinleyici dinliyorsa, aynı iki olayı defalarca tekrarlama çabasından tasarruf eder.
Agriculturist

5

İşte bulduğum çözüm: temel olarak, boş bir reactiveValuesveri tutucu oluşturun ve ardından değerlerini iki ayrı observeEventörneğe göre değiştirin .

  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
olacaktır list(mainplot.click$click, input$spec_button)da OP'ın yol için çalışıyorum.
John

1

Bu, eylemlerinizi bir vektöre yerleştirerek eventReactive ile yapılabilir.

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

0

Buradaki fikir, observeEvent'e iletmek istediğiniz koşulu yürütecek reaktif bir işlev oluşturmak ve ardından ifadenin geçerliliğini kontrol etmek için bu reaktif işlevi geçebilirsiniz. Örneğin:

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(), 
    { ... } 
)

Kodlamaya Devam Edin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.