Reputation: 1645
I have a huge shiny app and met with the below issue. I tried to provide pseudo code for the problem since it is nearly impossible for my expertize to creating working app to demonstrate the problem. I hope i have conveyed with the pseudo code. Kindly help me.
Here is the pseudo code in ui.R file which has an actionButton
and a radioButton
with underlying selectizeInput
and checkboxGroupInput
input options and plotOutput
to render a plot.
###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")
)
)
)
)
)
Below is the pseudo server.R code that observes the user input values and updates updateSelectizeInput
and updateCheckboxGroupInput
with choice
from the default loaded R dataset. The user selected
choices are used in the subsequent function to generate plot.
###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
)
})
})
Pseudo Code for R functions in plot.R file
####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
}
The tmpdat
and subdat
are the inputs to generate the plot in plot_render
function. If the user selects and inputs values through selectizeInput
then the subsetting of data should be done by samples. If the user selects and input through checkBoxGroupInput
then the subsetting should be done by group as commented in the code. I am not unable to subset the data based on user selection i.e. sample/group reactively in plot_subdat
function. How can i do this reactively so that the output plot is generated as per the user selection.
Upvotes: 0
Views: 1098
Reputation: 30474
I think you might want a reactive
expression to subset your data.
Here is a basic working example that includes your inputs, and will plot subsetted data based on input selections reactively.
Edit:
The filtering of data is now in an external .R file, with input
variables to filter on passed through.
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))
}
Upvotes: 1