如何通过用户选择对数据进行子集化以在 R Shiny 应用程序中进行绘图

How to subset data by user selection for plotting in R shiny app

我有一个闪亮的大应用程序,但遇到了以下问题。我试图为该问题提供伪代码,因为我的专业知识几乎不可能创建有效的应用程序来演示该问题。我希望我已经用伪代码传达了。请帮助我。

这是 ui.R 文件中的伪代码,它有一个 actionButton 和一个 radioButton 以及基础 selectizeInputcheckboxGroupInput 输入选项和 plotOutput 渲染图。

###ui.R#####

tabPanel("Plots",  
     fluidRow(column(4,wellPanel(
       actionButton("action_plot","Generate Plots"),  
       h6(textOutput("numheat")),
       radioButtons("plot_subset",label="Chose by sample or group?",
                    choices=c("Sample","Group"),selected="Sample"),

       conditionalPanel("input.plot_subset=='Sample'",
                        selectizeInput("view_sample_plot",
                                       label = h5("Select Samples"),
                                       choices = NULL,
                                       multiple = TRUE,
                                       options = list(placeholder = 'select samples to plot')
                        )
       ),
       conditionalPanel("input.plot_subset=='Group'",
                        checkboxGroupInput("view_group_plot",
                                           label=h5("Select Groups to View"),
                                           choices="",
                                           selected="")
       )
     )
     ),
     column(8,
            tabsetPanel(
              tabPanel(title="Plot",
                       #textOutput("which_genes"),
                       h4(textOutput("plot_title")),
                       plotOutput("plot_rna",height="800px")
     )
     )
     )
     )
     )

下面是伪 server.R 代码,它观察用户输入值并从默认加载的 R 数据集中用 choice 更新 updateSelectizeInputupdateCheckboxGroupInput。用户 selected 选择用于后续函数生成绘图。

###server.R#####

## observed the user input and updated the selectize input and checkBoxGroup input values#####
observe({
  print("server-plot-update")
  # browser()
  data_analyzed = inputData()
  tmpgroups = data_analyzed$group_names
  tmpdatlong = data_analyzed$data_long
  tmpsamples = unique(tmpdatlong$sampleid)
  tmpynames = tmpdatlong$

  updateSelectizeInput(session,'view_sample_plot',
                       choices=tmpsamples, selected=NULL)
  updateCheckboxGroupInput(session,'view_group_plot',
                           choices=tmpgroups, selected=NULL)

})        

    #####code to render plot based on user selection value i.e. by group or samples######
    ##plot_render utilizes the R functions in Plot.R file to subset the data by user input and generate plot###

    plotdatReactive <- reactive({
     data_analyzed = inputData
     tmp <- plot_data(data_analyzed = data_analyzed,
                               yname="log2",
                               orderby="significance",
                               view_group=input$view_group_plot,
                               view_sample=input$view_sample_plot)
     tmp
    })


    output$plot_rna <- renderPlot({
      if(input$action_plot==0) return()   
    isolate({
      tmp = plotdatReactive()
      plot_render( data_analyzed=tmp,
                   yname = input$heatmapvaluename,
                   view_group=input$view_group_plot,
                   view_sample=input$view_sample_plot
                   )
    })  
 })

plot.R 文件中的 R 函数的伪代码

    ####plot.R#####

    ###function to subset data based on user input samples or groups###
    plot_subdat <- function(data_analyzed,
                               yname="log2",
                               orderby="significance",
                               view_sample=NULL,
                               view_group=NULL) {

      if(is.null(view_sample)) view_sample=unique(data_analyzed$sampleid)  ## sample names in the dataset
      if(is.null(view_group)) view_group=data_analyzed$group_names ## group names in the dataset


      tmpdat = data_analyzed$data_long

      ##subset dataset by **sampleid** if the user selected **samples** in SelectizeInput
      tmpdat = tmpdat%>%filter(sampleid%in%view_sample)
      subdat = filter(data_analyzed$data_long,unique_id%in%thesegenes,sampleid%in%view_sample)


      #subset dataset by **group** if the user selected **group** in checkBoxGroup input
      tmpdat = tmpdat%>%filter(group%in%view_group)
      subdat = filter(data_analyzed$data_long,unique_id%in%thesegenes,group%in%view_group)

    }


###this function generates the plot on the subset of data from the above function#####

  plot_data <- function(...)  {
  tmpdat = plot_subdat(...)
  plotdat = tmpdat$data
  plotdat
  }

tmpdatsubdat 是在 plot_render 函数中生成绘图的输入。如果用户通过 selectizeInput 选择并输入值,则数据的子集化应由样本完成。如果用户通过 checkBoxGroupInput 选择和输入,那么子集应该按照代码中的注释按组完成。我无法根据用户选择对数据进行子集化,即 sample/group 在 plot_subdat 函数中反应。我怎样才能反应性地做到这一点,以便根据用户选择生成输出图。

我认为您可能需要 reactive 表达式来对数据进行子集化。

这是一个基本的工作示例,其中包含您的输入,并将根据输入选择反应地绘制子集数据。

编辑

数据过滤现在在外部 .R 文件中,input 变量过滤通过。

library(shiny)

source("plot.R", local = TRUE)

ui <- fluidPage(
  mainPanel(
    tabsetPanel(
      tabPanel("Plots",  
         fluidRow(column(4,wellPanel(
           #actionButton("action_plot","Generate Plots"),  
           h6(textOutput("numheat")),
           radioButtons("plot_subset",label="Chose by sample or group?",
                        choices=c("Sample","Group"),selected="Sample"),

           conditionalPanel("input.plot_subset=='Sample'",
                            selectizeInput("view_sample_plot",
                                           label = h5("Select Samples"),
                                           choices = NULL,
                                           multiple = TRUE,
                                           options = list(placeholder = 'select samples to plot')
                            )
           ),
           conditionalPanel("input.plot_subset=='Group'",
                            checkboxGroupInput("view_group_plot",
                                               label=h5("Select Groups to View"),
                                               choices="",
                                               selected="")
           )
         )),
         column(8,
                tabsetPanel(
                  tabPanel(title="Plot",
                           #textOutput("which_genes"),
                           h4(textOutput("plot_title")),
                           plotOutput("plot_rna",height="800px")
                  )
                )
         )
        )
      )
    )
  )
)

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

  observe({
    updateSelectizeInput(session,'view_sample_plot',
                           choices=unique(mtcars$gear), selected=NULL)
    updateCheckboxGroupInput(session,'view_group_plot',
                             choices=unique(mtcars$cyl), selected=NULL)
  })    

  plot_prepare <- reactive({
    if (input$plot_subset == "Sample") {
      plot_subdat(mtcars, "gear", input$view_sample_plot)
    } else {
      plot_subdat(mtcars, "cyl", input$view_group_plot)
    } 
  })

  output$plot_rna <- renderPlot({
    plot(plot_prepare())
  })

}

shinyApp(ui, server)

plot.R

# plot.R file

library(tidyverse)

plot_subdat <- function(data, variable, choices) {
  data %>%
    filter((!!sym(variable)) %in% choices) %>%
    select(c(!!sym(variable), mpg))
}