简体   繁体   English

是否可以在 2 个选项卡 [Shiny] 中使用相同的 actionButton?

[英]Is it possible to have the same actionButton in 2 tabs [Shiny]?

I am trying to create an app which has 3 tabs:我正在尝试创建一个具有 3 个选项卡的应用程序:

  • Tab 1 > it has a checkboxInput that if you click on it, you will do the log2 transformation. Tab 1 > 它有一个checkboxInput输入,如果单击它,您将执行 log2 转换。 In addition, it has one actionButton to submit your data (with or without log2)此外,它有一个actionButton来提交您的数据(有或没有 log2)
  • Tab 2 > it has a sliderInput which allows you to change the bins of the histogram. Tab 2 > 它有一个sliderInput ,允许您更改直方图的 bin。 It has another actionButton , but this time, to show the plot.它还有另一个actionButton ,但这次显示的是 plot。
  • Tab 3 > it has a numericInput that allows you to change the opacity of the plot.选项卡 3 > 它有一个numericInput ,允许您更改 plot 的不透明度。 In addition, it has the same actionButton that you find in Tab 2.此外,它具有与选项卡 2 中相同的actionButton

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.但是,当我更改选项卡 3 中的不透明度并想更新 plot 时,选项卡 3 中的actionButton不起作用。 However, if you click the actionButton from Tab 2 after having changed the opacity, the plot updates.但是,如果在更改不透明度后单击选项卡 2 中的actionButton ,plot 会更新。

图 1

So... for that reason, I was wondering if there was a way to have the same actionButton in two tabs.所以......出于这个原因,我想知道是否有办法在两个选项卡中使用相同的actionButton

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.请注意,如果我在actionButton完成时放置tabsetPanel ,则actionButton在 Tab 3 中工作,但它出现在 Tab 1 中,这是我不想要的。 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"),

    )
  )
)

图 2

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.另一方面,我正在考虑创建两个不同的按钮......因此,我必须将新按钮添加到observeEvent ......但是,我想在这里问一下,以防万一有人知道如何做到这一点创建一个新按钮。

Thanks very much in advance首先十分感谢

Regards问候

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.您不能有两个或多个具有相同 ID 的输入,但这并不意味着您需要有两个observEvent

Change the ID of the second button:更改第二个按钮的 ID:

tabPanel("Tab3",
                 numericInput("alpha", "Opacity of the histogram", value=0.2),
                 actionButton("show_plot_2", "See the plot")

And change the oberveEvent as below:并将oberveEvent更改如下:

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.但是,请注意现在用户可以更改 bin 数量,不要单击“查看绘图”按钮,go 为 tab3,更改不透明度,单击“查看绘图”,plot 将根据新的 bin 数量进行更新和新的不透明度 - 考虑这是否会让用户感到惊讶。 If you don't want this, then indeed you will need two observeEvent s.如果你不想要这个,那么你确实需要两个observeEvent

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:).我看到只有在 session 中至少单击一次input$submit时才会显示 plot,这对我来说看起来很奇怪,所以我留下这个注释:)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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