Home > front end >  How to efficiently subset a dataframe in R Shiny?
How to efficiently subset a dataframe in R Shiny?

Time:10-19

In the below example code I reactively subset the mtcars dataframe inside the renderPlot() function. However, in my larger App with many render functions in the server section I am having to repeat the same rv$x[1:input$samples], etc., over and over in many places. How would I apply this subsetting instead "at the top", into the rv <- reactiveValues(...) function itself or equivalent "master function"? I tried subsetting inside the reactiveValues() and got the message "Warning: Error in : Can't access reactive value 'samples' outside of reactive consumer. Do you need to wrap inside reactive() or observer()?" I assumed incorrectly that the reactiveValues() function is a "reactive consumer".

If someone can answer this basic understanding question, please explain the logic for correctly subsetting "at the top" because I am getting very embarrassed by my repeated questions about Shiny reactivity.

library(shiny)

ui <- fluidPage(
  sliderInput('samples','Nbr of samples:',min=2,max=32,value=16),
  plotOutput("p")
)

server <- function(input, output, session) {
  
  rv <- reactiveValues(
    x = mtcars$mpg,
    y = mtcars$wt
  )
  
  output$p <- renderPlot({plot(rv$x[1:input$samples],rv$y[1:input$samples])})

}

shinyApp(ui, server)

CodePudding user response:

There are multiple ways you can handle this.

Here is one way to create new subset reactive values inside observe.

library(shiny)

ui <- fluidPage(
  sliderInput('samples','Nbr of samples:',min=2,max=32,value=16),
  plotOutput("p")
)

server <- function(input, output, session) {
  
  rv <- reactiveValues(
    x = mtcars$mpg,
    y = mtcars$wt
  )
  
  observe({
    rv$x_sub <- rv$x[1:input$samples]
    rv$y_sub <- rv$y[1:input$samples]
  })
  
  output$p <- renderPlot({plot(rv$x_sub,rv$y_sub)})
  
}

shinyApp(ui, server)

enter image description here

CodePudding user response:

I'd use reactiveValues only if you need them to be modified in different places.

reactive is shiny's basic solution for this:

library(shiny)
library(datasets)

ui <- fluidPage(
  sliderInput(
    'samples',
    'Nbr of samples:',
    min = 2,
    max = 32,
    value = 16
  ),
  plotOutput("p")
)

server <- function(input, output, session) {
  reactive_mtcars <- reactive({mtcars[1:input$samples,]})
  output$p <- renderPlot({
    plot(reactive_mtcars()$mpg, reactive_mtcars()$wt)
  })
}

shinyApp(ui, server)
  • Related