3MW (Event listeners with R-Shiny)

Guten Tag!

Many greetings from Munich, Germany. Last week, we learned about the anatomy of a Shiny app. Today, we take this a bit further and figure out how we can trigger events. This helps us to display information whenever we want e.g. when we click on a button. But first, time for my usual announcements:

Creating beautiful tables in R & Python

The {gt} package is a fantastic package to create nice tables from within R. And the really cool thing is that there’s a Python version of that too. It’s called great_tables. In my newest YT video, I show you how this Python version works.

As always, all code that you see here can be found on Github.

Setting up a simple shiny app

First, let us set up a little Shiny app. Let’s throw in

  • a slider input using sliderInput(),

  • an action button using actionButton(), and

  • a text output using textOutput().

Using the things we learned last time, the server is set up so that the textOutput displays the value selected via sliderInput.

You can see here that inside of my renderText(), I put in a print statement. And for good reason. Let’s fire up a Shiny app and see what happens when we interact with it.

On the user interface, things work but the button is kind of useless. And on the console, we see that the value of the button is printed. This button shows you how often the button was already clicked.

Thus, this app reacts all the time. When I click the button, something in the console is printed. And when I drag the slider, a new output is shown in the output.

Controlling reactivity

Typically, you don’t want to run calculations whenever any input changes. Usually, you want to have more control at what time the server starts to compute things. For example, you could say you only want to display something when the button was first clicked.

That’s where the req() function comes in. In there, you can specify the conditions that are required for subsequent code to run. For example, here we might require that the number of times the button was already clicked is larger or equal to one.

That way, no matter how many times I drag my slider, the app doesn’t execute the subsequent code in the render function before I first click on the button. But the moment I click on the button, we can see now that the app reacts all the time when I click or when I drag the slider.

Isolating inputs

Next, let us see how we can isolate inputs. That way, we can ensure that the app reacts only those inputs that we want it to react to (like the button) This sort of thing can be done with the isolate() function. Let’s use it to isolate input$slider.

That way, when I drag the slider, the app doesn’t react. And to be clear, the app doesn’t react because we isolated the input within that renderText(). And that’s why there is no reactivity when draging the slider.

But if we click the button that whole render call is executed and we see the output change. This happens because the renderText() call has a dependency on the value of the button (via the print() and req() calls).

Using bindEvent() instead of isolate()

If you use a lot of inputs in a render call, wrapping all of them into isolate() can be quite tedious. Especially, when all you want is to solely react on a button click. And to avoid that tedious work, you cna pass your render call to the bindEvent() function. That way, all of your inputs in that render call are isolated automatically.

observeEvent() vs bindEvent()

There is a very similar function to bindEvent() called observeEvent(). From a code perspective, it looks fairly identical to bindEvent().

Basically, all we did here was to

  • use the thing we want to react on into the first argument of observeEvent() and

  • add all of the code (mind the {}) that we want to have executed in case the event happens as a second argument to observeEvent().

However, this doesn’t spare you the trouble of having to use isolate(). So that’s why I prefer bindEvent() over observeEvent().

So with that, we’ve learned how to create a small Shiny app. As always, hope you enjoyed this newsletter. Next week, we’ll talk about dynamic/reactive events in Shiny. And if you have any questions, don’t hesitate to reply to this mail or contact me on LinkedIn.

See you next week,
Albert 👋

Enjoyed this newsletter? Here are other ways I can help you:

Join the conversation

or to participate.