简体   繁体   中英

Incompatibility between selectizeInput and checkboxInput in Shiny

I am creating an app that it takes a file from one directory and takes the column names to give to the user the chance to decide which sample wants to work with.

Instead of uploading a file, I have created a dataframe (similar to my file) and I put it into reactive function (exactly what I usually do when I upload a file).

This is the dataframe

numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")

> df
  S1  S2 S3 S4
1  5 345 55 10

My app has a checkboxInput which you can decide if you want to do the logarithm or not to your dataframe.

If I want to compare S1 vs S2, I realised that when I don't click to into the box (and I don't do the logarithm) the samples don't change. That is what I want.

图片1

However, if I decide to do the logarithm (I click into the checkbox) the sample 2 changes (now it compares S1 vs S1, something that I don't really understand why and I don't want to).

图像2

This is the code:

library(shiny)

# Define UI 
ui <- fluidPage(

    # Application title
    titlePanel("My app"),


    sidebarLayout(
        sidebarPanel(
            uiOutput("selected_sample_one"),
            uiOutput("selected_sample_two"),
            checkboxInput("change_log2", "Log2 transformation", value = F),
            
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("plot")
        )
    )
)

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

    data <- reactive({
        numbers <- c(5,345,55,10)
        df<-data.frame(t(numbers))
        names(df) <- c("S1", "S2", "S3", "S4")

        if(input$change_log2 == TRUE){
            df <- log2(df)
        }
        return(df)
    })
    
    
    samples_names <- reactive({
        samples <- colnames(data())
        return(samples)
    })
    
    
    output$selected_sample_one <- renderUI({
        selectizeInput(inputId = "sample_one_axis", "Select the 1st sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
    })
    
    # With this function you can select which sample do you want to plot in the y-axis.
    output$selected_sample_two <- renderUI({
        selectizeInput(inputId = "sample_two_axis", "Select the 2nd sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
    })
    
    output$plot <- renderPlot({
        barplot(c(data()[,input$sample_one_axis], data()[,input$sample_two_axis]))
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

Note:

If I save the column names into a vector, the logarithm and everything works. Instead of using

 samples_names <- reactive({
         samples <- colnames(data())
         return(samples)
     })

If I use: samples_names <- c("S1", "S2", "S3", "S4") and I change output$selected_sample_one and output$selected_sample_two with this new vector samples_names , the second sample doesn't change (see the new picture)

图像3

HOWEVER, if I increase the number of columns or if I change the table, this code won't work. For that reason I wrote it inside a reactive function...

Does anyone know how to solve this?

Thanks very much in advance

That is because your reactive dataframe includes checkbox info, and sample_names depends on that dataframe. To separate them, create a new dataframe where you perform the log operation, leaving the initial dataframe without log transformation. Try this

library(shiny)

# Define UI 
ui <- fluidPage(
  
  # Application title
  titlePanel("My app"),
  
  sidebarLayout(
    sidebarPanel(
      uiOutput("selected_sample_one"),
      uiOutput("selected_sample_two"),
      checkboxInput("change_log2", "Log2 transformation", value = F)
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("plot")
    )
  )
)

# Define server 
server <- function(input, output,session) {
  
  data <- reactive({
    
    numbers <- c(5,345,55,10)
    df<-data.frame(t(numbers))
    names(df) <- c("S1", "S2", "S3", "S4")
    
    return(df)
  })
  
  data1 <- eventReactive(input$change_log2,{
    df <- data()
    if(input$change_log2 == TRUE){
      df <- log2(df)
    }
    return(df)
  })
  
  samples_names <- reactive({
    req(data())
    samples <- colnames(data())
    return(samples)
  })
  
  output$selected_sample_one <- renderUI({
    selectizeInput(inputId = "sample_one_axis", "Select the 1st sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
  })
  
  # With this function you can select which sample do you want to plot in the y-axis.
  output$selected_sample_two <- renderUI({
    selectizeInput(inputId = "sample_two_axis", "Select the 2nd sample", choices=samples_names(), selected=samples_names()[2], options=list(maxOptions = length(samples_names())))
  })
  
  output$plot <- renderPlot({
    req(input$sample_one_axis,input$sample_two_axis,data1())
    barplot(c(data1()[,input$sample_one_axis], data1()[,input$sample_two_axis]))
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM