Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a reactive function outside the shiny app

Tags:

module

r

shiny

I am trying to decompose the code of my shiny app in order to improve readability and to test some functions using the testthat package.

I would like to have some files (for example server_utils.R) in which I can write "normal" functions that I can test and then make them reactive.

For example I would like to have something like this in server_utils.R:

my_sum <- function(x, y) {
  x + y
}

and something like this in the app:

my_sum_reactive(input$x, input$y)

Do you know if a such behavior is possible?

like image 202
amarchin Avatar asked May 15 '17 09:05

amarchin


People also ask

How do you make a reactive function Shiny?

A reactive expression is an R expression that uses widget input and returns a value. The reactive expression will update this value whenever the original widget changes. To create a reactive expression use the reactive function, which takes an R expression surrounded by braces (just like the render* functions).

What is reactive function in Shiny?

Reactivity is how Shiny determines which code in server() gets to run when. Some types of objects, such as the input object or objects made by reactiveValues() , can trigger some types of functions to run whenever they change.

Which function is used to create the Shiny app?

shinyApp. Finally, we use the shinyApp function to create a Shiny app object from the UI/server pair that we defined above. We save all of this code, the ui object, the server function, and the call to the shinyApp function, in an R script called app. R .


Video Answer


1 Answers

Shiny modules is what might help you.

See here: https://shiny.rstudio.com/articles/modules.html

As you can read in the article the desired functionality to pass in input is possible if you wrap the input in a reactive() function. (See the end of the "Writing server functions" section of the article).

You would define the my_sum function as follows: (Note that you have to use the variables a and b as reactives a() and b() and wrap the result in a reactive() function.)

my_sum <- function(input, output, session, a, b) {
  reactive(as.numeric(a()) + as.numeric(b()))
}

And could use it as:

my_sum_reactive <- callModule(my_sum, "id", reactive(input$a), reactive(input$b))

which is then usable as:

my_sum_reactive()

Reproducible example:

library(shiny)

my_sum <- function(input, output, session, a, b) {
  reactive(as.numeric(a()) + as.numeric(b()))
}

ui <- fluidPage({
  fluidRow(
    selectInput("a", "a", 1:3),
    selectInput("b", "b", 1:3),
    textOutput("txt")
  )
})

server <- function(input, output, session) {
  my_sum_reactive <- callModule(my_sum, "id", reactive(input$a), reactive(input$b))
  output$txt <- renderText(paste0("The sum is: ", my_sum_reactive())) 
}
shinyApp(ui, server)
like image 189
Tonio Liebrand Avatar answered Sep 30 '22 12:09

Tonio Liebrand