【问题标题】:How can I show different plots depending on the user's input in Shiny?如何根据用户在 Shiny 中的输入显示不同的图?
【发布时间】:2021-07-27 17:11:06
【问题描述】:

我有这个数据框:

> df
  genes  enst  x  y
1 Gene1 ENST1 25 14
2 Gene1 ENST2 60 25
3 Gene1 ENST3 12  5
4 Gene2 ENST1  9 34
5 Gene2 ENST2 14 12
6 Gene3 ENST1 10  1

我正在尝试创建一个闪亮的应用程序,它允许我选择基因和转录本。如果您选择一个基因(例如,Gene1),您将可以选择您想要的转录本(在本例中为 ENST1、ENST2、ENST3)。

问题是我想绘制 2 个图。如果您单击“基因”(级别:基因),它将对该基因的所有值求和。 例如,对于第一个基因,它有 3 个转录本,x 的总值将为 20+60+12=92,y 的总值将为 14+25+5=44)。所以绘制基因 1 的值将是:x=92 和 y=44。

此外,我想绘制每个成绩单。例如,如果您选择“Gene1”和“Transcript 1”,则绘图将使用 x=25 和 y=14。但是,如果用户决定选择两个成绩单,用户将看到 2 个图。或者如果用户选择 3 个成绩单,用户将看到 3 个不同的图。

现在,使用我的代码: 如果您选择基因,您将获得基因图。

但是,它会在同一个图中显示所有成绩单。而且我只想显示一份成绩单(或更多,如果用户愿意)

我不知道如何继续。

另一方面,有两件事我不知道如何实现。

  • “查看情节”操作按钮。 --- 如果你点击它,它会显示你的情节。
  • 单选按钮“级别” --- 如果您单击基因,它只会显示基因图。但是,如果您点击成绩单,它会显示成绩单图。

谁能帮帮我?提前致谢

我的代码:

library(shiny)

################ DATA #############################
genes<- c("Gene1", "Gene1", "Gene1", "Gene2", "Gene2", "Gene3")
enst <- c("ENST1", "ENST2", "ENST3", "ENST1", "ENST2", "ENST1")
x <- c(25, 60, 12, 9, 14, 10)
y <- c(14, 25, 5, 34, 12, 1)
df<- data.frame(genes, enst, x, y)

###################################################

ui <- fluidPage(
  
  # Application title
  titlePanel("Barplot"),
  
  sidebarLayout(
    sidebarPanel(
      uiOutput("selected_gene"),
      uiOutput("selected_transcript"),
      radioButtons("level", "Level:",
                   c("Gene" = "Gene",
                     "Transcript" = "Transcript")),
      h5(strong("If you want to see the plot, you have to click the button")),
      actionButton("add_plot", "See the plot"),
    ),
    
    mainPanel(
      plotOutput("plot"),
      plotOutput("plot2"),
  
      tableOutput("table1"),
      tableOutput("table2")
    )
  )
)


server <- function(session, input, output) {
  
  
  # This function gives us the list of genes.
  genes_list <- reactive({
    df$genes
    })
  
  transcripts_list <- reactive({
    
    transcripts <- subset(df, df$genes==input$gene)
    transcripts <- transcripts[,2]
    return(transcripts)
  })
  
  # This function give us a select list input, in order to be able to select the gene that we want to see
  output$selected_gene <- renderUI({
    selectizeInput(inputId = "gene", "Select one gene", choices=genes_list(), options=list(maxOptions = length(genes_list())))
  })
  
  output$selected_transcript <- renderUI({
    selectizeInput(inputId = "transcript", "Select one transcript", choices=transcripts_list(), options=list(maxOptions = length(transcripts_list())), multiple=T)
  })
  
  
  gene_values <- reactive({
    
    values <- subset(df, df[1]==input$gene)
    values$enst <- NULL
    
    if(nrow(values)>1){ #for those genes who have more than 1 transcript
      values_new <- values[2:length(values)] 
      values_new <- as.data.frame(t(colSums(values_new))) # sum the columns, transpose and transform into a dataframe
      
      gene <- values[1,] #we take the first row, only one gene but all the info.
      
      values <- cbind(values_new, gene[1]) # we bind both dataframes, however, we only want the gene name
      values <- values[,c("genes",setdiff(names(values),"genes"))] # we move the last column at the beginning
    }
    return(values)
    
  })
    
  transc_values <- reactive({

    values <- subset(df, df[1]==input$gene)
    values$genes <- NULL
  
    return(values)
  })
  
  plot_genes <- reactive({
    gene_values <- gene_values()
    barplot(c(gene_values$x, gene_values$y))
    
  })
  
  plot_transc <- reactive({
    transc_values <- transc_values()
    barplot(c(transc_values$x, transc_values$y))
    
  })
  
  
  v <- reactiveValues(plot = NULL)
  
  observeEvent(input$add_plot, {
    if(input$level == "Gene"){
      v$plot <- plot_genes()
    }
    if(input$level == "Transcript"){
      v$plot <- plot_transc()
    }
  })
  
  # This function will draw the plot
  # output$plot <- renderPlot({
  #   if (is.null(v$plot)){
  #     return()
  #   }
  #   v$plot
  # })
  
  

  output$table1 <- renderTable(gene_values())
  output$table2 <- renderTable(transc_values())
  
  output$plot <- renderPlot(plot_genes())
  output$plot2 <- renderPlot(plot_transc())
  
  
}

shinyApp(ui, server)

【问题讨论】:

    标签: r plot shiny user-input selectinput


    【解决方案1】:

    也许你可以从这个开始,根据你的需要进行修改。

    library(shiny)
    library(ggplot2)
    library(DT)
    ################ DATA #############################
    genes<- c("Gene1", "Gene1", "Gene1", "Gene2", "Gene2", "Gene3")
    enst <- c("ENST1", "ENST2", "ENST3", "ENST1", "ENST2", "ENST1")
    x <- c(25, 60, 12, 9, 14, 10)
    y <- c(14, 25, 5, 34, 12, 1)
    df<- data.frame(genes, enst, x, y)
    
    ###################################################
    
    ui <- fluidPage(
      
      # Application title
      titlePanel("Histogram"),
      
      sidebarLayout(
        sidebarPanel(
          uiOutput("selected_gene"),
          uiOutput("selected_transcript"),
          radioButtons("level", "Level:",
                       c("Gene" = "Gene",
                         "Transcript" = "Transcript")),
          h5(strong("If you want to see the plot, you have to click the button")),
          div(actionButton("add_plot", "See the plot"), 
              actionButton("table", "See the table"),
              actionButton("clear", "Clear All")
              )
        ),
        
        mainPanel(
          plotOutput("plot"),
          DTOutput("table")
        )
      )
    )
    
    
    server <- function(input, output, session) {
      
      
      ## This function gives us the list of genes.
      genes_list <- reactive({
        unique(df$genes)
      })
      
      transcripts_list <- reactive({
        req(input$gene)
        transcripts <- subset(df, df$genes==input$gene)
        transcripts <- transcripts[,2]
        return(unique(transcripts))
      })
      
      # This function give us a select list input, in order to be able to select the gene that we want to see
      output$selected_gene <- renderUI({
        selectizeInput(inputId = "gene", "Select one gene", choices=genes_list(), options=list(maxOptions = length(genes_list())))
      })
      
      output$selected_transcript <- renderUI({
        selectizeInput(inputId = "transcript", "Select one transcript", choices=transcripts_list(), options=list(maxOptions = length(transcripts_list())), multiple=F)
      })
      
      
      gene_values <- reactive({
        req(input$gene)
        values <- subset(df, df[1]==input$gene)
        values$enst <- NULL
        
        if(nrow(values)>1){ #for those genes who have more than 1 transcript
          values_new <- values[2:length(values)] 
          values_new <- as.data.frame(t(colSums(values_new))) # sum the columns, transpose and transform into a dataframe
          
          gene <- values[1,] #we take the first row, only one gene but all the info.
          
          values <- cbind(values_new, gene[1]) # we bind both dataframes, however, we only want the gene name
          values <- values[,c("genes",setdiff(names(values),"genes"))] # we move the last column at the beginning
        }
        return(values)
        
      })
      
      transc_values <- reactive({
        req(input$transcript)
        values <- subset(df, df[2]==input$transcript)
        values$genes <- NULL
        
        return(values)
      })
      
      mydata <- reactive({
        req(input$level)
        if(input$level == "Gene"){
          df <- req(gene_values())
        }else if(input$level == "Transcript"){
          df <- req(transc_values())
        }else df <- NULL
        df
      })
      
      # plot_genes <- reactive({
      #   gene_values <- req(gene_values())
      #   barplot(c(gene_values$x, gene_values$y))
      #   
      # })
      # 
      # plot_transc <- reactive({
      #   transc_values <- req(transc_values())
      #   barplot(c(transc_values$x, transc_values$y))
      #   
      # })
      
      
      v <- reactiveValues(plot = NULL, table=NULL)
      
      observeEvent(input$add_plot, {
        v$plot <- ggplot(mydata(), aes(x=x,y=y)) + geom_bar(stat = "identity")
        v$table <- NULL  ### display only plot
      },ignoreInit = TRUE)
      
      observeEvent(input$table, {
        v$table <- req(mydata())
        v$plot <- NULL   ### display only table
      },ignoreInit = TRUE)
      
      observeEvent(input$clear, {
        v$table <- NULL
        v$plot <- NULL
      },ignoreInit = TRUE)
      
      ##  This function will draw the plot
      output$plot <- renderPlot({ v$plot })
      output$table <- renderDT({ v$table })
      
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 令人印象深刻,非常感谢!是否可以同时显示两个图?例如,如果一个基因有 2 个转录本并且用户选择了 BOTH 转录本,他能看到这两个图吗?或者如果一个基因有 3 个转录本,而用户只想看 2 个,他是否只能看到两个图?
    • 是的。你可以显示任何你想要的 - 在observeEvent(input$add_plot, {...})中定义它,然后创建一个新的output$plot2...
    • 但是...如果您不知道用户想要多少地块?因为按照你所说的,你需要知道用户想要多少图,在你的代码中写“output$plotX”
    猜你喜欢
    • 2018-05-24
    • 2021-09-30
    • 2021-12-29
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2021-03-20
    相关资源
    最近更新 更多