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.
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).
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)
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)