Adding more than one graph to mainPanel in Shiny (R) - r

I am trying to have multiple html outputs in my shiny App but it seems like it can only show one at a time.
My UI is:
# ui.R
shinyUI(
mainPanel(
tableOutput("view"),
plotOutput("view2")
))
And my server is:
# server.R
library(googleVis)
library(RMySQL)
shinyServer(function(input, output) {
datasetInput <- reactive({
"try2" = subset(try1, idCampaign == input$inputId)
})
output$view <- renderGvis({
gvisTable(datasetInput(),options=list(width=1000, height=270, col='blue'))
})
output$view2 <- renderGvis({
gvisScatterChart(datasetInput2())
})
})

in the output to view2 you use datasetInput2() , this should be datasetInput(). Here datasetInput() just represents a dynamic version of a dataframe, you can use it in as many functions as you want, there is no need to index it.

alternatively i think you can use the tabsetPanel to divide your main page into certain parts and assign output objects to each of your tabPanel.

Related

Assigning reactive expression twice ignores first one

Shiny beginner here: I want to load a different dataset depending on which action-button gets clicked on. Since the processing from there on will be the same for any dataset, I want to store them in the same reactive expression, here dataset().
See my code:
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("gohere", "dataset1"),
actionButton("gothere", "dataset2")
),
mainPanel(
tableOutput("dataset")
),
)
)
)
server <- function(input, output) {
dataset <- eventReactive(input$gohere, {
mtcars
})
dataset <- eventReactive(input$gothere, {
cars
})
output$dataset <- renderTable({
dataset()
})
}
shinyApp(ui = ui, server = server)
I expect this code to load mtcars into dataset when actionButton "gohere" is clicked and proceed with renderTable and to load cars into dataset when actionButton "gothere" is clicked and proceed likewise.
However: If I click actionButton "gothere" everything works as expected, if I click "gohere" nothing happens. If I change the order of "gohere" and "gothere" inside the server- function it's the other way around.
What does the second eventReactive() do with dataset that completly invalidates the first eventReactive() ?
EDIT: And if it is overwriting it, what is it overwriting it with?
This works like ordinary R programming: your two reactive conductors are R objects with the same name, so the second one overwrites the first one.
You can use a reactive value and some observers:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("gohere", "dataset1"),
actionButton("gothere", "dataset2")
),
mainPanel(
tableOutput("dataset")
),
)
)
server <- function(input, output) {
dataset <- reactiveVal(mtcars)
observeEvent(input$gohere, {
dataset(mtcars)
})
observeEvent(input$gothere, {
dataset(cars)
})
output$dataset <- renderTable({
dataset()
})
}
shinyApp(ui = ui, server = server)

Subsetting dataframe based on dynamically generated checkBoxGroupInput: checkbox keeps resetting

I would like to use a Shiny app to load a file (tab-separated), dynamically create a checkboxGroupInput, after the loading of the file (using observeEvent) using the column headers, then subset the data frame that comes from the file based on the selected checkboxes. The data is then plotted using code I can't share right now.
All is working fine, apart from the last bit: subsetting the dataframe based on the selected checkboxes in checkboxGroupInput. The checkboxes all start selected, and the plot is created fine. If you un-select one of the checkboxes, the plot re-plots appropriately for a split second (so the subsetting is working fine) then the unselected checkbox re-selects itself and the plot goes back to the old plot.
This is the tiny problem I'm trying to solve, guessing it's one line of code. I'm assuming it's because of some reactivity that I don't understand and the checkbox constantly resetting itself.
Here is an example:
###
## Some functions I can't share
### Shiny app
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("MagicPlotter"),
# Sidebar
sidebarLayout(
sidebarPanel(
fileInput(inputId = "myInputID",
label = "Your .csv file",
placeholder = "File not uploaded"),
uiOutput("mylist"),
uiOutput("submitbutton")
),
# Show a plot
mainPanel(
verticalLayout(
plotOutput("myPlot"))
)
)
)
# Define server
server <- function(input, output) {
output$myPlot <- renderPlot({
inputfile <- input$myInputID
if(is.null(inputfile))
{return()}
mydataframe <- read.table(file=inputfile$datapath, sep="\t", head=T, row.names = 1)
mydataframecolumnnames <- colnames(mydataframe[1:(length(mydataframe)-1)])
# the last column is dropped because it's not relevant as a column name
observeEvent(input$myInputID, {
output$mylist <- renderUI({
checkboxGroupInput(inputId="mylist",
label="List of things to select",
choices=mydataframecolumnnames,
selected=mydataframecolumnnames)
})
})
observeEvent(input$myInputID, {
output$submitbutton <- renderUI({
submitButton("Subset")
})
})
mysubset <- mydataframe[input$mylist]
myPlot(mysubset)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Thanks all
I think there are a few things that might help...
One, you can move your observeEvent methods outside of your renderPlot.
Also, you can create a reactive function to read in the data table.
I hope this helps.
server <- function(input, output) {
myDataFrame <- reactive({
inputfile <- input$myInputID
if(is.null(inputfile))
{return()}
read.table(file=inputfile$datapath, sep="\t", head=T, row.names = 1)
})
output$myPlot <- renderPlot({
req(input$mylist)
mysubset <- myDataFrame()[input$mylist]
plot(mysubset)
})
observeEvent(input$myInputID, {
mydata <- myDataFrame()
mydataframecolumnnames <- colnames(mydata[1:(length(mydata)-1)])
output$mylist <- renderUI({
checkboxGroupInput(inputId="mylist",
label="List of things to select",
choices=mydataframecolumnnames,
selected=mydataframecolumnnames)
})
})
observeEvent(input$myInputID, {
output$submitbutton <- renderUI({
submitButton("Subset")
})
})
}

Create dynamic amount of tables inside a tabsetpanel R Shiny

I'm trying to create an dynamic amount of datatables inside a tabsetPanel argument. Thanks to various different posts here I came to this 'not working solution'.
The tables are rendered and accesed correctly but the tabsetPanel fails to create and I'm wondering how I can make this work, any help appreciated:
library(DT)
# for simplification this is not dynamic but created without hardcoded variable calls.
portalData <- lapply(1:10,function(x)data.frame(rnorm(5,1))
names(portalData) <- 1:10
shinyApp(
ui = pageWithSidebar(
headerPanel("Dynamic number of tables inside tabpanels"),
sidebarPanel(
),
mainPanel(
uiOutput("tables")
)
),
server = function(input, output) {
observe({
output$tables <- renderUI({
names_list <- lapply(seq_along(portalData), function(i){
tablename <- paste(names(portalData)[i])
tabPanel(dataTableOutput(tablename))
})
do.call(tabsetPanel,do.call(tagList, names_list))
})
for(i in 1:length(portalData)){
local({
i2 <- i
output[[names(portalData)[i2]]] <- renderDataTable({portalData[[i2]]})
})
}
})
})

How to embed a value from a reactive dataset in a tags() function in shiny?

In the shiny app below, I would like to print out parts of the two reactive datasets (reactiveDf and reactive2) using the function tags but the script I have is not working.
I know I could use other solutions like renderTable, but later on I need to embed this reactive code in a html page using {{}}, thus it would be wonderful if somebody can explain to me why this is not working.
library(shiny)
library(dplyr)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput('Category', '',
unique(mtcars$carb), selected = unique(mtcars$carb))),
# Show table of the rendered dataset
mainPanel(
tags$div(reactiveDf()),
tags$div(reactive2())
)
)
))
server <- shinyServer(function(input, output) {
reactiveDf <- reactive({return(tbl_df(mtcars) %>%
filter(carb %in% input$Category))})
reactive2 <- reactive({reactiveDf()[1,]})
})
shinyApp(ui = ui, server = server)

Shiny check reactiveValue existence with validate -- Not Found

I have a shiny code like in the below. I need to define variables as reactiveValues to be updatable (or I could define them I think as global but then I have to press clean objects from Rstudio which is not very user-friendly).I try to run a validate code to check for existence of the data I have defined as reactiveValues. validate(need(exists("GSEmRNA$d"),message="Dataframe not found")) yields "Dataframe not found" thus, does not plot my boxplot. If I define them as global variables and forget to press clean objects, code might mix up as old data can be passed as if it is new. Any help is appreciated.
server.R
shinyServer(function(input, output) {
observeEvent(input$GoButton,{
dataset <- data.frame(first= c(1,5,9),second=c(8,5,13), third=c(10,3,17))
GSEmRNA <- reactiveValues(d=dataset)
})
output$BoxplotDataset <- renderPlot({
if (input$GoButton== 0) {return()}
else{
validate(need(exists("GSEmRNA$d"),message="Dataframe not found"))
boxplot(GSEmRNA$d)}
})
})
ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Dataset Selection"),
sidebarPanel(
actionButton("GoButton","GO")
),
mainPanel(
wellPanel(
column(8, plotOutput("BoxplotDataset")
)
)
)))
FOR THE RECORD, I ALSO POSTED THIS QUESTION TO SHINY GOOGLE DISCUSS GROUP https://groups.google.com/forum/#!topic/shiny-discuss/ZV5F6Yy-kFg
Here are the updated code. The points are:
library(shiny)
server <-shinyServer(function(input, output) {
GSEmRNA <- reactiveValues(d=NULL) #define it ouside
observeEvent(input$GoButton,{
dataset <- data.frame(first= c(1,5,9),second=c(8,5,13), third=c(10,3,17))
GSEmRNA$d <- dataset #assign it inside
})
output$BoxplotDataset <- renderPlot({
validate(need(GSEmRNA$d,"Dataframe not found")) # changed as well
boxplot(GSEmRNA$d)
})
})
ui <- pageWithSidebar(
headerPanel("Dataset Selection"),
sidebarPanel(
actionButton("GoButton","GO")
),
mainPanel(
wellPanel(
column(8, plotOutput("BoxplotDataset")
)
)
))
runApp(list(ui=ui,server=server))
Defined the reactiveValues outside of the observeEvent
Changed the reactiveValues inside of the observeEvent
Changed the validate and need.

Resources