rinputshinyreactiverenderui

How to use an input created in renderUI into a reactive function in R Shiny?


I created several two inputs in the UI: "slider0" and "slider1" and one in the server using renderUI "slider2". I am trying to use calculate a new column of a data-frame based on a conditional statement on slider0 and the values of slider1 and slider2.

I have the following reproducible code:

library(shiny)
library(DT)
library(dplyr)
library(shinydashboard)
library(htmltools)
library(shinyjs)

first_column <- c("15", "25")
second_column <- c("0.5", "50")

d0 <- data.frame(first_column, second_column)
d0[,1:2 ] <- sapply(d0[ ,1:2],as.numeric)


######################### header ##########
header <- dashboardHeader(
  title = "TEST")

################ Sidebar ################
sidebar <- dashboardSidebar(
  sidebarMenu(
    menuItem("Test", tabName = "Test"), 
    menuItem("Test2", tabName = "Test2")
  )
)

######################### body ##################

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "Test",
            fluidRow(
              column(width = 4,
                box(width = NULL, solidHeader = TRUE,
                         useShinyjs(), 
                         radioButtons(
                           inputId="slider0", 
                           label="slider0", 
                           choices = c("Yes"="Yes", "No"="No"), inline=TRUE),  
                         column(4,numericInput("slider1", "slider1", min = 0, max = 1, value = 0.25, step=0.05)),
                         column(4, uiOutput("slider2"))
                         )), 
              column(width = 8,
                     
                     box(width = NULL, solidHeader = TRUE,
                         DT::dataTableOutput(outputId = "mytable") 
                         
                     ))
            ))))

################# ui #############
ui<- dashboardPage(
  header,
  sidebar,
  body
)

################server ###############  
  server <- function(input, output) {

  output$slider2 <- renderUI({
    req(input$slider1)
    numericInput("slider2", "slider2", min = 0,  max = 1 , value = 1- input$slider1, step=0.05)
  }) 

  ############ This code does not have warning error when input$slide1 is used in mutate ##########
  d1<-reactive({
    if(input$slider0 == "Yes"){
      d0 %>%
        mutate(C3= first_column*input$slider2)
        
    } else {d0 }
  })

  output$mytable = renderDataTable({
    d1()
  })
  
}
#####
shinyApp(ui=ui, server=server) 

In the server I want to compute a new column C3 by multiplying a column of the data frame with input$slider2 defined with renderUI in the server.

I got the following error message: "Warning: Error in : Problem with mutate() input C3. x Input C3 can't be recycled to size 2. ℹ Input C3 is first_column * input$slider2. ℹ Input C3 must be size 2 or 1, not 0. 138: "

When I choose input$slider1 defined in the UI, I do not have any error/warnings message but I cannot figure out where is the issue.


Solution

  • You could require that input$server2 is defined and has a valid value before using it further:

    
      d1 <- reactive({
        if(input$slider0 == "Yes"){
      
          # Make sure that input$slider2 is ready to be used 
          req(input$slider2)
    
          # Will be executed as soon as above requirement is fulfilled
          d0 %>%
            mutate(C3= first_column*input$slider2)
          
        } else {d0 }
      })