I am a beginner coder and am working on a Rshiny Dashboard for the Rdata "BOD". Unfortunatley, non of my graphs are showing up on the Dashboard. I was wondering what mistakes i have made in my script as no errors are returned if I run the code.
This is my first post on stack overflow so I appologise if I haven't followed proper etiquette.
Thanks,
My Code:
library(shiny)
library(shinythemes)
library(tidyverse)
library(ggplot2)
library(DT)
library(forecast)
library(fpp)
library(tsbox)
library(hrbrthemes)
#Data preperation
data(BOD)
summary(BOD)
BODFrame <- data.frame(BOD)
Time <- BODFrame$Time
Demand <- BODFrame$demand
tsdata <- ts(BODFrame, frequency = 2)
ddata <- decompose(tsdata, "multiplicative")
plot(ddata)
seasonal <- (ddata$seasonal)
trend <- (ddata$trend)
random <- (ddata$random)
plot(seasonal)
plot(trend)
plot(random)
forecastframe <- auto.arima(BODFrame[,1])
myforecastframe <- forecast(forecastframe, level=c(60), h = 12)
plot(myforecastframe)
#creating UI
ui <- fluidPage(
titlePanel("Effect of Time on BOD (mg/1) Levels"),
navbarPage("Select Tab",
tabPanel("Explore The Data",
mainPanel(
tabsetPanel(
tabPanel("Line Graph", plotOutput("line"), br(), radioButtons("filetype", "Select file type", c("png", "jpeg")), downloadButton("dwd", "Download Graph")),
tabPanel("Histogram", plotOutput("hist"), br(), radioButtons("filetype", "Select file type", c("png", "jpeg")), downloadButton("dwd", "Download Graph"))
)
)
),
tabPanel("Stastical Decomposition of the Data",
sidebarLayout(
sidebarPanel(width = 3,
selectInput(inputId = "Models",
label = "Select Model:",
choices = c("Trend"=1, "Seasonality"=2, "Noise"=3),
selected = 1),
textOutput("text1")
),
mainPanel(
plotOutput("plot2"),
br(), radioButtons("filetype", "Select file type", c("png", "jpeg")), downloadButton("dwd", "Download Graph")
)
)
),
tabPanel("Forecasting BOD",
mainPanel(
plotOutput("Forecast"),
br(), radioButtons("filetype", "Select file type", c("png", "jpeg")), downloadButton("dwd", "Download Graph")
)
)
)
)
#Writing Server Logic
server <- function(input, output){
output$line <- renderPlot({
ggplot(BODFrame, aes(x = Time, y = Demand)) + geom_line(col = "cadetblue4", size = 2) + theme_ipsum() + ggtitle("BOD (mg/1) vs Time") +
geom_point(col = "red", size = 3)
})
output$hist <- renderPlot({
ggplot(data = BODFrame) + geom_histogram(bins = 6, breaks = c(1:7), mapping = aes(x = Time, y = ..Demand..),
col = "cadetblue4") + theme_ipsum() + ggtitle("BOD (mg/1) vs Time Histogram")
})
output$plot2 <- renderPlot({
if (input$Models == 1){
plot(trend, main = "Decomposed Trend - BOD")
}
else if (input$Models == 2){
plot(seasonal, main = "Decomposed Seasonality - BOD")
}
else if (input$Models == 3){
plot(random, main = "Decomposed Noise - BOD")
}
})
output$Forecast <- renderPlot({
plot(myforecastframe, main = "Forecasted Level of BOD (mg/1)")
})
output$text1 <- renderText({
if (input$Models == 1){
paste0("The increasing or decreasing value of BOD in the series")
}
else if (input$Models == 2){
paste0("The repeating short term cycle of the BOD series.")
}
else if (input$Models == 3){
paste0("The random variation in the BOD series.")
}
})
}
shinyApp(ui = ui, server = server)
Related
TD <- thyroid
library(readxl)
library(shiny)
library(ggplot2)
library(shinythemes)
library(DT)
ui <-shinyUI(fluidPage(pageWithSidebar(
headerPanel("Test App"),
sidebarPanel(
selectInput("xaxis", "Choose a x variable", choices = names(TD)),
selectInput("T4", "T4 Rate", choices = c("All","0 - 80","80 - 140","> 140")),
selectInput("T3", "T4 Rate", choices = c("All","0 - 80","80 - 140","> 140")),
selectInput("TSH", "T4 Rate", choices = c("All","0 - 80","80 - 140","> 140")),
actionButton("goButton","Update")
),
mainPanel(
tabsetPanel(
tabPanel('Plot1', plotOutput("plot1")),
tabPanel('Plot2', plotOutput("plot2"))
))
)
))
server <- shinyServer(function(input,output, session){
data1 <- reactive({
if(input$T4 == "All"){
TD
}
else if(input$T4 == "0 - 80"){
TD[which(TD$T4 >= 0 & TD$T4 < 80),]
}
else if(input$T4 == "80 - 140"){
TD[which(TD$T4 >= 80 & TD$T4 < 140),]
}
else{
TD[which(TD$T4 >= 140),]
}
})
x_var<- eventReactive(input$goButton, {
input$xaxis
})
output$plot1 <- renderPlot({
x <- x_var()
p <- ggplot() + geom_bar(aes(x=TD[[x]], fill = TD$ThryroidClass))
p #+
#theme(plot.title = element_text(hjust = 0.5, size=20))
})
output$plot2 <- renderPlot({
x <- x_var()
p <- ggplot() + geom_bar(aes(x=data1[[x]], fill = TD$ThryroidClass))
p #+
#theme(plot.title = element_text(hjust = 0.5, size=20))
})
})
shinyApp(ui,server)
I m working on the thyroid dataset
i wanna compare groups of patients which are probably sick from thyroid based on the T4 rate.
THis is why i have created a subset of my original according to that rate.
i have done 2 plos, the one with the whole dataset works perfectly, but the second with the sub set five me the followinf error : Error[object object]
How can i handle this please??
I have two SelectInput Drowpdown controls but I can't make the first one reactive. My second control works fine. Consider this small toy example: On my first dropdown (which it doesn't work), I have 5 options. I want this control to react when the selection changes. I basically want both of my dropdown controls to be reactive to the type of model or type of graphic selected.
library(shiny)
library(ggplot2)
library(tidyverse)
library(shinythemes)
library(plotly)
library(scales)
library(shinyWidgets)
library(shinydashboard)
library(DT)
library(shinyjs)
library(shinycssloaders)
# Define input choices
type <- c("lambda","indices")
model <- c("Output_21yr_noStock","Output_21yr_yesStock","Output_82yr_bdc_noStock","Output_82yr_ppp_noStock","Output_82yr_woa_nostock")
#############Lambda######Table
olddir <- getwd()
table <- structure(list(year = 1991:2010, lambda = c(0.73392, 0.75659,
1.33665, 1.06641, 1.27145, 1.01077, 0.66983, 1.6427, 0.96414,
0.55648, 0.50556, 1.08024, 0.8706, 0.89665, 1.00807, 1.01967,
0.73131, 1.1161, 1.10219, 1.35085)), row.names = c(NA, -20L), class = "data.frame")
table
# Define UI
ui <- fluidPage(
useShinyjs(), # to initialise shiny
theme = shinytheme("superhero"),
navbarPage("Species: Pink Salmon",
windowTitle = "Salmon Model Application",
sidebarPanel(width = 3,
h3("Select Model Output"),
selectInput(inputId = "model",
label = "Model to Run",
choices = model,
selected = "Output_21yr_noStock"),
selectInput(inputId = "graphtype",
label = "Graphic",
choices = type,
selected = "lambda"),
#Slider to select custom years
chooseSliderSkin("Square"),
setSliderColor(c("LightSeaGreen ", "#FF4500", "", "Teal"), c(1, 2, 4)),
#tags$style(type = "text/css", ".irs-grid-pol.small {height: 0px;}"), #hide small ticks
sliderInput(inputId = "Yearslider",
label = "Years to plot",
sep = "",
min = min(table$year), #min and max values of spawner_maturity table6
max = max(table$year),
step = 1,
value = c(min = min(table$year),max = max(table$year))
)),
#Graphic Area mainPanel. Graphic on top and table right below it
mainPanel(
plotOutput("plot")
)))
server<- function (input, output, session) {
session$onSessionEnded(function() {
stopApp()
})
plot_data <- reactive({
table[table$year >= input$Yearslider[1] & table$year <= input$Yearslider[2], ]
})
dataInput <- reactive({
switch(input$graphtype,
"lambda" = plot_data())
})
#How can I make the "model" SelectInput drowpdown control reactive when I select a different model? The "modelInput" below is not reacting.
modelInput <- reactive({
switch(input$model,
"Output_21yr_noStock" = input$model,
"Output_21yr_yesStock" = input$model)
})
# Plot data
create_plots <- reactive({
theme_set(theme_classic(14))
xlabels <- c(min(table$year):max(table$year))
if (input$graphtype == "lambda") {
ggplot(plot_data(),aes(year,lambda)) + geom_line(size=1.5,colour="blue") +
geom_point(colour="orange",size=4) + geom_hline(yintercept=1,color="hotpink",linetype="dashed") +
scale_x_continuous("",breaks = xlabels) + legendTheme +
theme(axis.text.x = element_text(angle = 45, vjust = 0.5)) +
labs(x="",y=expression("Lambda ("~lambda *")"),
title= paste0("Modeled Population growth rate of Delta Smelt cohort years ",
table[table$year >= input$Yearslider[1] & table$year <= input$Yearslider[2], ]))
}
})
#Render plots
output$plot <- renderPlot({
create_plots()
},height = 475)
}
# Run the application
shinyApp(ui = ui, server = server)
How can I reset the graph to display a blank plot? I've created a reset button and have tried various recommendations, but they usually cause some sort of problem or they do nothing at all.
ui <- fluidPage(
theme = shinytheme("cerulean"),
navbarPage( "Unemployment Rate Comparison Tool",
tabPanel("Interactive Graph",
titlePanel("US Unemployment Rates Before and After COVID-19"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "y",
label = "Select State(s) to Graph",
choices = unique(q_long$State),
selected = "United States",
multiple = TRUE
), # select input end
radioButtons(
inputId = "x",
label = "Displaying Unemployment Rates for 2013-2022",
choices = c("Year"),
selected = "Year"
), # Radio buttons end
actionButton("run_plot", "Run Plot"),
actionButton("reset", "Clear Output"),
), # side bar panel end
mainPanel(
span(strong("Compare State Unemployment Rates Pre and Post COVID.", style = "color:black"),style = "font-si16pt"),
div("Select the state(s) you wish to view from the drop down menu. Once you have made your selections, click \"Run Plot\"."),
br(),
plotlyOutput(outputId = "graph"),
) # Main panel end
) # select input end
), #navbar interactive graph
tabPanel("Data", DT::dataTableOutput(outputId="datasheet"))# navbar data end
) #Navbar end
) # fluid page end
server <- function(input, output, session) {
q_filtered <- eventReactive(input$run_plot, {
filter(q_long, State %in% input$y)
})
output$graph <- renderPlotly({
ggplot(q_filtered(), aes(x = .data[[input$x]], y = unemployment, color = State)) + geom_point() + geom_line() + geom_vline(aes(xintercept = 2020)) + scale_x_continuous(breaks = q$year)
}) # render plotly end
output$datasheet<-DT::renderDataTable({
DT::datatable(data=q,
rownames=FALSE)}
)
} # server end
shinyApp(ui = ui, server = server)
I am just really not sure what to do from here
Maybe like this (not tested):
server <- function(input, output) {
Plot <- reactiveVal()
q_filtered <- eventReactive(input$run_plot, {
filter(q_long, State %in% input$y)
})
observe({
gg <- ggplot(q_filtered(), aes(x = .data[[input$x]], y = unemployment, color = State)) + geom_point() + geom_line() + geom_vline(aes(xintercept = 2020)) + scale_x_continuous(breaks = q$year)
Plot(gg)
})
observeEvent(input$reset, {
Plot(plotly_empty())
})
output$graph <- renderPlotly({
Plot()
})
output$datasheet <- DT::renderDataTable({
DT::datatable(data=q,
rownames=FALSE)}
)
} # server end
Good morning,
in my dashboard I inserted a checkbox to select one or more output to display. In the ui I entered the checkbox and in the server all the conditions (if ... else if ...). When I launch the app it only shows me a plot, even when I select more than one choice in the checkbox. In addition it gives me this error in console:
"Warning in if (input$checkGroup == 1) { :the condition has length > 1 and only the first element will be used"
I suppose it's telling me that I can't handle more than one choice, how do I view all the plots I choose?
ui <- fluidPage(titlePanel("IULM Dashboard"), sidebarLayout(sidebarPanel(
selectInput("selection", "Choose a Dataset:",
choices = datasets),
("Barplot","Network",'Wordcloud', "LDA-Latent topic"),
#selected = "Barplot", inline = TRUE),
checkboxGroupInput("checkGroup", label = ("Checkbox group"),
choices = list("Barplot" = 1, "Network" = 2), selected = 1, inline = TRUE),
actionButton("update", "Change"))
, mainPanel(
uiOutput("plot")))
server <- function(input, output){
datasetInput <- reactive({
input$update
isolate({
withProgress({
setProgress(message = "Processing corpus...")
getTermMatrix(input$selection)
})
})
})
output$plot <- renderUI({
if(input$checkGroup== 1 ){
output$barplot <- renderPlot({
v=datasetInput()
dtm1 = removeSparseTerms(v, 0.992)
freq <- colSums(as.matrix(dtm1))
wf = data.frame(term = names(freq), occurrences = freq)
wf <- wf[order(wf$occurrences, decreasing = TRUE),]
wf2 = subset(wf[1:input$maxB,])
ggplot(wf2, aes(term, occurrences)) +
geom_bar(stat="identity", fill="darkred", colour="black", width=0.5)+
theme(axis.text.x=element_text(angle=45, hjust=1))+
ggtitle("Word barplot")})
plotOutput(outputId = "barplot", width = 600, height = 400)
}
else if(input$checkGroup== 2 ){
output$network <- renderPlot({
v=datasetInput()
dtm1 = removeSparseTerms(v, 0.992)
rowTotals <- apply(dtm1 , 1, sum)
dtm2 <- dtm1[rowTotals> 0, ]
wdtm <- weightTf(dtm2)
dtm1 <- removeSparseTerms(wdtm, 0.96)
dfm <- as.dfm(dtm1)
textplot_network(dfm, min_freq = 0.5, omit_isolated = TRUE,
edge_color = "#1F78B4", edge_alpha = 0.5, edge_size = 2,
vertex_color = "#4D4D4D", vertex_size = 2,
vertex_labelsize = 5, offset = NULL)})
plotOutput(outputId = "network", width = 600, height = 600)}
})
}
shinyApp(ui = ui, server = server)
You can try
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput("variable", "Variables to show:",
c("Cylinders" = "cyl",
"Transmission" = "am",
"Gears" = "gear"))
),
mainPanel(
uiOutput("plots")
)))
server <- function(input, output) {
output$plots <- renderUI({
req(input$variable)
output = tagList()
if(any(input$variable %in% "cyl")){
tmp <- mtcars$cyl
output[[1]] <- renderPlot({plot(mtcars$mpg, tmp)})
}
if(any(input$variable %in% "am")){
tmp <- mtcars$am
output[[2]] <- renderPlot({boxplot(mtcars$mpg, tmp)})
}
output
})
}
shinyApp(ui = ui, server = server)
I am using shiny and shinydashboard. There are a couple of instances when I would like all or most boxes/plots to be hidden.
If the date range is impossible (i.e. the end date is earlier than the start date).
If inputs selected make the sample size too small.
With issue 1, I want to hide all the boxes and just return an error message. With issue 2, I'd like to show a few infoboxes at the top (e.g. sample size), but hide all the rest of the boxes.
Currently, I am producing an error message using validate for the first condition, and also using validate to stop the plots from running when this happens. However, this still leaves the boxes, even though they are empty, which is quite ugly and messy.
I would probably be able to put every box into a conditionalPanel, I guess, but that seems very repetitive - surely there is a simpler way to pass an argument to all (or a group of) boxes? This code is an example - there are a lot more boxes in the app I am working on.
Example code:
library(shiny)
library(shinydashboard)
library(tidyverse)
random_data <- data.frame(replicate(2, sample(0:10, 1000, rep=TRUE)))
set.seed(1984)
random_data$date <- sample(seq(as.Date('2016-01-01'), as.Date(Sys.Date()), by = "day"), 1000)
sidebar <- dashboardSidebar(dateRangeInput(
"dates", label = h4("Date range"), start = '2016-01-01', end = Sys.Date(),
format = "dd-mm-yyyy", startview = "year", min = "2016-01-01", max = Sys.Date()
))
body <- dashboardBody(
textOutput("selected_dates"),
br(),
fluidRow(
infoBoxOutput("total", width = 12)
),
fluidRow(
box(width = 12, solidHeader = TRUE,
title = "X1 over time",
plotOutput(outputId = "x1_time")
)
),
fluidRow(
box(width = 12, solidHeader = TRUE,
title = "X2 over time",
plotOutput(outputId = "x2_time")
)
)
)
ui <- dashboardPage(dashboardHeader(title = "Example"),
sidebar,
body
)
server <- function(input, output) {
filtered <- reactive({
filtered_data <- random_data %>%
filter(date >= input$dates[1] & date <= input$dates[2])
return(filtered_data)
})
output$selected_dates <- renderText({
validate(
need(input$dates[2] >= input$dates[1], "End date is earlier than start date"
)
)
})
output$total<- renderInfoBox({
validate(
need(input$dates[2] >= input$dates[1], "")
)
infoBox(title = "Sample size",
value = nrow(filtered()),
icon = icon("binoculars"), color = "light-blue")
})
output$x1_time <- renderPlot({
validate(
need(input$dates[2] >= input$dates[1], "")
)
x1_time_plot <- ggplot(filtered(), aes(x = date, y = X1)) +
geom_bar(stat = "identity")
theme_minimal()
x1_time_plot
})
output$x2_time <- renderPlot({
validate(
need(input$dates[2] >= input$dates[1], "")
)
x2_time_plot <- ggplot(filtered(), aes(x = date, y = X2)) +
geom_bar(stat = "identity")
theme_minimal()
x2_time_plot
})
}
shinyApp(ui, server)
You could use shinyjs and the show/hide method on all the inputIds that you want to hide or show or you can put all the boxes in a div with a class and use the hide/show with this class or assign a class directly to the fluidRows.
With both examples validate+need is not required anymore.
This example shows/hides the individual output IDs:
library(shiny)
library(shinydashboard)
library(tidyverse)
library(shinyjs)
## DATA ##################
random_data <- data.frame(replicate(2, sample(0:10, 1000, rep=TRUE)))
set.seed(1984)
random_data$date <- sample(seq(as.Date('2016-01-01'), as.Date(Sys.Date()), by = "day"), 1000)
sidebar <- dashboardSidebar(dateRangeInput(
"dates", label = h4("Date range"), start = '2016-01-01', end = Sys.Date(),
format = "dd-mm-yyyy", startview = "year", min = "2016-01-01", max = Sys.Date()
))
##################
## UI ##################
body <- dashboardBody(
useShinyjs(),
textOutput("selected_dates"),
br(),
fluidRow(
infoBoxOutput("total", width = 12)
),
fluidRow(
box(width = 12, solidHeader = TRUE,
title = "X1 over time",
plotOutput(outputId = "x1_time")
)
),
fluidRow(
box(width = 12, solidHeader = TRUE,
title = "X2 over time",
plotOutput(outputId = "x2_time")
)
)
)
ui <- dashboardPage(dashboardHeader(title = "Example"),
sidebar,
body
)
##################
server <- function(input, output) {
filtered <- reactive({
filtered_data <- random_data %>%
filter(date >= input$dates[1] & date <= input$dates[2])
return(filtered_data)
})
observe({
if (input$dates[2] < input$dates[1]) {
shinyjs::hide("total")
shinyjs::hide("x1_time")
shinyjs::hide("x2_time")
} else {
shinyjs::show("total")
shinyjs::show("x1_time")
shinyjs::show("x2_time")
}
})
output$total<- renderInfoBox({
infoBox(title = "Sample size",
value = nrow(filtered()),
icon = icon("binoculars"), color = "light-blue")
})
output$x1_time <- renderPlot({
x1_time_plot <- ggplot(filtered(), aes(x = date, y = X1)) +
geom_bar(stat = "identity")
theme_minimal()
x1_time_plot
})
output$x2_time <- renderPlot({
x2_time_plot <- ggplot(filtered(), aes(x = date, y = X2)) +
geom_bar(stat = "identity")
theme_minimal()
x2_time_plot
})
}
shinyApp(ui, server)
This example uses classes for the fluidRows, so this will hide the whole main page of the dashboard:
## UI ##################
body <- dashboardBody(
useShinyjs(),
textOutput("selected_dates"),
br(),
fluidRow(class ="rowhide",
infoBoxOutput("total", width = 12)
),
fluidRow(class ="rowhide",
box(width = 12, solidHeader = TRUE,
title = "X1 over time",
plotOutput(outputId = "x1_time")
)
),
fluidRow(class ="rowhide",
box(width = 12, solidHeader = TRUE,
title = "X2 over time",
plotOutput(outputId = "x2_time")
)
)
)
ui <- dashboardPage(dashboardHeader(title = "Example"),
sidebar,
body
)
##################
server <- function(input, output) {
filtered <- reactive({
filtered_data <- random_data %>%
filter(date >= input$dates[1] & date <= input$dates[2])
return(filtered_data)
})
observe({
if (input$dates[2] < input$dates[1]) {
shinyjs::hide(selector = ".rowhide")
} else {
shinyjs::show(selector = ".rowhide")
}
})
output$total<- renderInfoBox({
infoBox(title = "Sample size",
value = nrow(filtered()),
icon = icon("binoculars"), color = "light-blue")
})
output$x1_time <- renderPlot({
x1_time_plot <- ggplot(filtered(), aes(x = date, y = X1)) +
geom_bar(stat = "identity")
theme_minimal()
x1_time_plot
})
output$x2_time <- renderPlot({
x2_time_plot <- ggplot(filtered(), aes(x = date, y = X2)) +
geom_bar(stat = "identity")
theme_minimal()
x2_time_plot
})
}
shinyApp(ui, server)