I am trying to create an app which has 3 tabs:
- Tab 1 > it has a
checkboxInput
that if you click on it, you will do the log2 transformation. In addition, it has oneactionButton
to submit your data (with or without log2) - Tab 2 > it has a
sliderInput
which allows you to change the bins of the histogram. It has anotheractionButton
, but this time, to show the plot. - Tab 3 > it has a
numericInput
that allows you to change the opacity of the plot. In addition, it has the sameactionButton
that you find in Tab 2.
It works perfectly. However, when I change the opacity in Tab 3 and I want to update the plot, the actionButton
from the Tab 3 doesn't work. However, if you click the actionButton
from Tab 2 after having changed the opacity, the plot updates.
So... for that reason, I was wondering if there was a way to have the same actionButton
in two tabs.
The code:
library(shiny)
library(dplyr)
library(ggplot2)
hist_function <- function(DF, bins, alpha){
hist <- DF %>%
ggplot(aes(value))
geom_histogram(aes(y=..density.., fill = id), bins=bins, col="black", alpha=alpha)
geom_density()
facet_grid(id ~ .)
ggtitle("My histogram....")
theme(strip.text.x = element_blank(),strip.text.y = element_blank())
return(hist)
}
ui <- fluidPage(
titlePanel("My app"),
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel("Tab1",
checkboxInput("log2", "Log2 transformation", value = FALSE),
actionButton("submit", "Submit")
),
tabPanel("Tab2",
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 10),
actionButton("show_plot", "See the plot")
),
tabPanel("Tab3",
numericInput("alpha", "Opacity of the histogram", value=0.2),
actionButton("show_plot", "See the plot")
)
)
),
mainPanel(
plotOutput("histogram"),
)
)
)
server <- function(input, output) {
val1 <- c(2.1490626,3.7928443,2.2035281,1.5927854,3.1399245,2.3967338,3.7915825,4.6691277,3.0727319,2.9230937,2.6239759,3.7664386,4.0160378,1.2500835,4.7648343,0.0000000,5.6740227,2.7510256,3.0709322,2.7998003,4.0809085,2.5178086,5.9713330,2.7779843,3.6724801,4.2648527,3.6841084,2.5597235,3.8477471,2.6587736,2.2742209,4.5862788,6.1989269,4.1167091,3.1769325,4.2404515,5.3627032,4.1576810,4.3387921,1.4024381,0.0000000,4.3999099,3.4381837,4.8269218,2.6308474,5.3481382,4.9549753,4.5389650,1.3002293,2.8648220,2.4015338,2.0962332,2.6774765,3.0581759,2.5786137,5.0539080,3.8545796,4.3429043,4.2233248,2.0434363,4.5980727)
val2 <- c(3.7691229,3.6478055,0.5435826,1.9665861,3.0802654,1.2248374,1.7311236,2.2492826,2.2365337,1.5726119,2.0147144,2.3550348,1.9527204,3.3689502,1.7847986,3.5901329,1.6833872,3.4240479,1.8372175,0.0000000,2.5701453,3.6551315,4.0327091,3.8781182)
data <- reactive({
df1 <- data.frame(value = val1)
df2 <- data.frame(value = val2)
data_df <- bind_rows(lst(df1, df2), .id = 'id')
})
mydata <- reactive({
req(input$submit)
if(input$log2 == TRUE){
data <- data()
cols <- sapply(data, is.numeric)
data[cols] <- lapply(data[cols], function(x) log2(x 1))
}
else{
data <- data()
}
return(data)
})
v <- reactiveValues()
observeEvent(input$show_plot, {
v$plot <- hist_function(DF=mydata(), bins=input$bins, alpha=input$alpha)
})
output$histogram <- renderPlot({
req(input$submit)
if (is.null(v$plot)) return()
v$plot
})
}
shinyApp(ui = ui, server = server)
Note that if I put the actionButton
when the tabsetPanel
finishes, the actionButton
works in Tab 3, but it appears in Tab 1, which I don't want. I only want to have the submit button in that tab.
ui <- fluidPage(
titlePanel("My app"),
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel("Tab1",
checkboxInput("log2", "Log2 transformation", value = FALSE),
actionButton("submit", "Submit")
),
tabPanel("Tab2",
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 10),
#actionButton("show_plot", "See the plot")
),
tabPanel("Tab3",
numericInput("alpha", "Opacity of the histogram", value=0.2),
#actionButton("show_plot", "See the plot")
)
),
actionButton("show_plot", "See the plot") ### THIS IS THE NEW BUTTON
),
mainPanel(
plotOutput("histogram"),
)
)
)
On the other hand, I was thinking to create two different buttons... and therefore, I would have to add the new one to the observeEvent
... but, I wanted to ask here just in case someone knows how to do it without creating a new button.
Thanks very much in advance
Regards
CodePudding user response:
You can't have two or more inputs with the same IDs, but it doesn't mean you need to have two observEvent
s in your case.
Change the ID of the second button:
tabPanel("Tab3",
numericInput("alpha", "Opacity of the histogram", value=0.2),
actionButton("show_plot_2", "See the plot")
And change the oberveEvent
as below:
observeEvent(input$show_plot | input$show_plot_2, {
v$plot <- hist_function(DF=mydata(), bins=input$bins, alpha=input$alpha)
})
However, please note that now user can change number of bins, do not click the "see the plot" button, go to tab3, change the opacity, click "see the plot" and plot will be updated taking into account new number of bins and new opacity - take into account if this will be surprising for user or not. If you don't want this, then indeed you will need two observeEvent
s.
I see that plot is displayed only if input$submit
is clicked at least once in session, it looks strange for me, so I'm leaving this note :).