could can tell me why error when change dataset in first selectinput widget? when change dataset diamonds mtcars error could not find 'carat' in input$bins , in plot 1 second , after works fine. why happened?
library(shiny) library(ggplot2) data(diamonds) data(mtcars) ui <- fluidpage( column(3, selectinput("data", "", choices = c('mtcars', 'diamonds')), uioutput('server_cols'), uioutput('server_bins') ), column(9, plotoutput("plot") ) ) server <- function(input, output) { data <- reactive({ switch(input$data, diamonds = diamonds, mtcars = mtcars) }) output$server_cols <- renderui({ data <- data() nam <- colnames(data) selectinput('cols', "choose numeric columns:", choices = nam[sapply(data, function(x) is.numeric(x))]) }) output$server_bins <- renderui({ if (!is.null(input$cols)) { df <- data() x <- eval(input$cols) max_value <- max(df[,x]) sliderinput('bins','choose number of bins:', min = 0.1, max = max_value, value = max_value/2) } }) output$plot <- renderplot({ if (!is.null(input$cols) & !is.null(input$bins)) { basicdata <- data() var <- eval(input$cols) ggplot(basicdata, aes_string(var)) + geom_histogram(binwidth = input$bins, color = 'white', fill = 'red') } }) } shinyapp(ui, server)
your respective output objects respond changes of input variables. thus, when change dataset via input$data, plot rebuilds itself, although input$cols did not yet adjust. actually, try inserting print("a") inside output$plot see called 3 times if change input$data.
the fix rethink reaction logic , let elements respond specific changes, kind of response "thread".
for example, input$data should trigger output$server_cols. , output$server_bins should triggered input$cols (because implies input$data changed earlier). ultimately, output$plot has listen changes of input$bins (because changes in input$cols , input$data result in changes of input$bins since @ end of thread).
here suggestion using isolate.
library(shiny) library(ggplot2) data(diamonds) data(mtcars) ui <- fluidpage( column(3, selectinput("data", "", choices = c('mtcars', 'diamonds')), uioutput('server_cols'), uioutput('server_bins') ), column(9, plotoutput("plot") ) ) server <- function(input, output) { data <- reactive({ switch(input$data, diamonds = diamonds, mtcars = mtcars) }) output$server_cols <- renderui({ data <- data() nam <- colnames(data) selectinput('cols', "choose numeric columns:", choices = nam[sapply(data, function(x) is.numeric(x))]) }) output$server_bins <- renderui({ if (!is.null(input$cols)) { df <- isolate(data()) x <- eval(input$cols) max_value <- max(df[,x]) sliderinput('bins','choose number of bins:', min = 0.1, max = max_value, value = max_value/2) } }) output$plot <- renderplot({ if (!is.null(isolate(input$cols)) & !is.null(input$bins)) { basicdata <- isolate(data()) var <- eval(isolate(input$cols)) ggplot(basicdata, aes_string(var)) + geom_histogram(binwidth = input$bins, color = 'white', fill = 'red') } }) } shinyapp(ui, server) you might want updateselectinput , updatesliderinput if want alter input elements depending on other input.
Comments
Post a Comment