Let's consider my heatmap shiny code :
library(shiny)
library(plotly)
library(quantmod)
#Data
start <- as.Date("2013-01-01")
end <- as.Date("2016-10-01")
#Apple stock
getSymbols("AAPL", src = "yahoo", from = start, to = end)
apple <- AAPL$AAPL.Close
#Gold
getSymbols('GOLD', src = 'yahoo', from = start, to = end)
gold <- GOLD$GOLD.Close
#S&P
getSymbols('^GSPC', src = 'yahoo', from = start, to = end)
sp <- as.numeric(`GSPC`[,4])
#Microsoft
getSymbols('MSFT', src = 'yahoo', from = start, to = end)
msft <- MSFT$MSFT.Close
stock.frame <- data.frame(apple, gold, msft, sp)
colnames(stock.frame) <- c('apple', 'gold', 'msft', 'sp')
cmat <- cor(stock.frame)
plot_ly(z = cmat, type = "heatmap")
ui <- fluidPage(
mainPanel(
plotlyOutput("heatmap", width = "100%", height="600px")
)
)
## server.R
server <- function(input, output) {
output$heatmap <- renderPlotly({plot_ly(x = colnames(stock.frame), y = colnames(stock.frame), z = cmat, type = "heatmap") %>%
layout(
xaxis = list(title=colnames(stock.frame)),
yaxis = list(title="ts")
)
})
}
shinyApp(ui,server)
And my histogram :
UI
library(shiny) # load the shiny package
# Define UI for application
shinyUI(fluidPage(
# Header or title Panel
titlePanel(h4('Demostration of the renderPlot() - A Histogram with stock dataset', align = "center")),
# Sidebar panel
sidebarPanel(
selectInput("var", label = "1. Select the quantitative Variable",
choices = c("Apple" = 1, "Gold" = 2, "S&P" = 3, "BTC"=4),
selected = 3),
sliderInput("bin", "2. Select the number of histogram BINs by using the slider below", min=5, max=50, value=15),
radioButtons("colour", label = "3. Select the color of histogram",
choices = c("Green", "Red",
"Yellow"), selected = "Green")
),
# Main Panel
mainPanel(
textOutput("text1"),
textOutput("text2"),
textOutput("text3"),
plotOutput("myhist")
)
)
)
Sever
library(shiny) # Load shiny package
start <- as.Date("2013-01-01")
end <- as.Date("2016-10-01")
#Apple stock
getSymbols("AAPL", src = "yahoo", from = start, to = end)
apple <- AAPL$AAPL.Close
#Gold
getSymbols('GOLD', src = 'yahoo', from = start, to = end)
gold <- GOLD$GOLD.Close
#S&P500
getSymbols('^GSPC', src = 'yahoo', from = start, to = end)
sp <- as.numeric(`GSPC`[,4])
#Microsoft
getSymbols('MSFT', src = 'yahoo', from = start, to = end)
msft <- MSFT$MSFT.Close
stock.frame <- data.frame(apple, gold, msft, sp)
colnames(stock.frame) <- c('apple', 'gold', 'msft', 'sp')
shinyServer(
function(input, output) {
output$myhist <- renderPlot({
colm <- as.numeric(input$var)
hist(stock.frame[, colm], col = input$colour, xlim = c(min(stock.frame[, colm]), max(stock.frame[, colm])), main = "Histogram of stock dataset", breaks = seq(min(stock.frame[, colm]), max(stock.frame[, colm]), l = input$bin + 1), xlab = names(stock.frame[colm]))
})
}
)
What I want to have is a special list in which I can choose if I want to have heatmap or histogram. So speaking as simply as possible I want possibility to switch between heatmap or histogram in one app (because now I have two seperate apps). Do you any idea how it can be performed ?
One way to achieve this is to use conditionalPanel as shown below.
library(shiny)
library(quantmod)
start <- as.Date("2013-01-01")
end <- as.Date("2016-10-01")
#Apple stock
getSymbols("AAPL", src = "yahoo", from = start, to = end)
apple <- AAPL$AAPL.Close
#Gold
getSymbols('GOLD', src = 'yahoo', from = start, to = end)
gold <- GOLD$GOLD.Close
#S&P500
getSymbols('^GSPC', src = 'yahoo', from = start, to = end)
sp <- as.numeric(`GSPC`[,4])
#Microsoft
getSymbols('MSFT', src = 'yahoo', from = start, to = end)
msft <- MSFT$MSFT.Close
stock.frame <- data.frame(apple, gold, msft, sp)
colnames(stock.frame) <- c('apple', 'gold', 'msft', 'sp')
cmat <- cor(stock.frame)
### plot_ly(z = cmat, type = "heatmap")
### Define UI for application
ui <- fluidPage(
# Header or title Panel
titlePanel(h4('Demostration of the renderPlot() - A Histogram with stock dataset', align = "center")),
# Sidebar panel
sidebarPanel(
selectInput("var", label = "1. Select the quantitative Variable",
choices = c("Apple" = 1, "Gold" = 2, "S&P" = 3, "BTC"=4),
selected = 3),
sliderInput("bin", "2. Select the number of histogram BINs by using the slider below", min=5, max=50, value=15),
radioButtons("graphtype", label = "Select Type of Graph",
choices = c("Heatmap", "Histogram"), selected = "Heatmap"),
conditionalPanel(
condition = "input.graphtype == 'Histogram' ",
radioButtons("colour", label = "3. Select the color of histogram",
choices = c("Green", "Red", "Yellow"), selected = "Green")
)
),
# Main Panel
mainPanel(
textOutput("text1"),
textOutput("text2"),
textOutput("text3"),
conditionalPanel(
condition = "input.graphtype == 'Heatmap' ", plotlyOutput("heatmap", width = "100%", height="600px")
),
conditionalPanel(
condition = "input.graphtype == 'Histogram' ", plotOutput("myhist")
)
)
)
server <- function(input, output) {
output$myhist <- renderPlot({
colm <- as.numeric(input$var)
hist(stock.frame[, colm], col = input$colour, xlim = c(min(stock.frame[, colm]), max(stock.frame[, colm])), main = "Histogram of stock dataset", breaks = seq(min(stock.frame[, colm]), max(stock.frame[, colm]), l = input$bin + 1), xlab = names(stock.frame[colm]))
})
output$heatmap <- renderPlotly({plot_ly(x = colnames(stock.frame), y = colnames(stock.frame), z = cmat, type = "heatmap") %>%
layout(
xaxis = list(title=colnames(stock.frame)),
yaxis = list(title="ts")
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Related
I am trying to update the value in a plotly chart in R shiny whose calculated value depends on the number of inputs
library(shiny)
library(httr)
library(jsonlite)
library(dplyr)
library(plotly)
library(shinythemes)
library(flexdashboard)
library(shinydashboard)
setwd("X:/Work/Covid-19 Project/Shiny Dashboard")
rp_1 <- read.csv("Data/Risk Profile 1.csv")
rp_2 <- read.csv("Data/Risk Profile 2.csv")
gender <- c("Male","Female")
age <- c("Less than 20 years", "20 to 50 years","More than 50 years")
city <- c("Delhi","Chennai")
diabetes <- c("Have diabetes","Don't have diabetes")
hypertension <- c("Have hypertension","Don't have hypertension")
risk_level_est <- function(city, gender, age, db, ht){
p_inv <- as.numeric(rp_1 %>%
filter(City == city & Gender == gender) %>%
select(Prob))
p_adv <- as.numeric(rp_2 %>%
filter(Age == age & Diabetes == db & Hypertension == ht) %>%
summarise(Hosp + Death))
as.numeric(p_inv*p_adv*100)
}
sar_risk_level_est <- function(age, db, ht){
p_adv <- as.numeric(rp_2 %>%
filter(Age == age & Diabetes == db & Hypertension == ht) %>%
summarise(Hosp + Death))
as.numeric(0.2*p_adv*100)
}
about_page <- tabPanel(
title = "About",
titlePanel("About"),
"Created with R Shiny",
br(),
"2021 April"
)
main_page <- tabPanel(
title = "Estimator",
titlePanel(""),
sidebarLayout(
sidebarPanel(
title = "Inputs",
selectInput("gender", "Select your gender", gender),
selectInput("age", "Select your age", age),
selectInput("city", "Select your city", city),
selectInput("db", "Do you have diabetes", diabetes),
selectInput("ht", "Do you have hypertension", hypertension),
radioButtons("radio", "Do you want to include your household members",
choices = list("No" = 1,"Yes" = 2)),
conditionalPanel("input.radio == 2",
numericInput("members", label = "How many household members do you have?", value='1'),
uiOutput("member_input")
),
actionButton("risk","Calculate my risk profile")
),
mainPanel(
tabsetPanel(
tabPanel(
title = "Risk Profile",
plotlyOutput("risk_profile", height = 250, width = "75%"),
plotlyOutput("overall_risk_profile", height = 250, width = "75%")
)
)
)
)
)
ui <- navbarPage(
title = "Risk Estimator",
theme = shinytheme('united'),
main_page,
about_page
)
server <- function(input, output, session) {
output$member_input <- renderUI({
numMembers <- as.integer(input$members)
lapply(1:numMembers, function(i) {
list(tags$p(tags$u(h4(paste0("Member ", i)))),
selectInput(paste0("age", i), "Select their age", age, selected = NULL),
selectInput(paste0("db", i), "Do they have diabetes", diabetes, selected = NULL),
selectInput(paste0("ht", i), "Do they have hypertension", hypertension, selected = NULL))
})
})
risk_level <- eventReactive(input$risk, {
risk_level_est(input$city, input$gender, input$age, input$db, input$ht)
})
sar_risk_level <- eventReactive(input$risk,{
sar_risk <- 0
lapply(1:input$members, function(i){
sar_risk <- sar_risk + sar_risk_level_est(input[[paste0("age", i)]],input[[paste0("db", i)]],input[[paste0("ht", i)]])
})
as.numeric(sar_risk)
})
output$risk_profile <- renderPlotly({
fig <- plot_ly(
domain = list(x = c(0, 1), y = c(0, 1)),
value = risk_level(),
title = list(text = "Personal Risk Profile"),
type = "indicator",
mode = "gauge+number",
gauge = list(
axis = list(range = list(0, 15)),
bar = list(color = "gray"),
bgcolor = "white",
borderwidth = 2,
bordercolor = "gray",
steps = list(
list(range = c(0, 3.75), color = "darkgreen"),
list(range = c(3.75, 7.5), color = "chartreuse"),
list(range = c(7.5,11.25), color = "orange"),
list(range = c(11.25,15), color = "red")
)))
fig <- fig %>% layout(margin = list(l=30, r=30, t=80, b=30))
fig
})
output$overall_risk_profile <- renderPlotly({
fig <- plot_ly(
domain = list(x = c(0, 1), y = c(0, 1)),
value = risk_level() + sar_risk_level(),
title = list(text = "Overall Risk Profile"),
type = "indicator",
mode = "gauge+number",
gauge = list(
axis = list(range = list(0, 15+(25*input*members))),
bar = list(color = "gray"),
bgcolor = "white",
borderwidth = 2,
bordercolor = "gray",
steps = list(
list(range = c(0, 3.75), color = "darkgreen"),
list(range = c(3.75, 7.5), color = "chartreuse"),
list(range = c(7.5,11.25), color = "orange"),
list(range = c(11.25,15), color = "red")
)))
fig <- fig %>% layout(margin = list(l=30, r=30, t=80, b=30))
fig
})
}
shinyApp(ui, server)
While the risk_profile plot works fine, the overall_risk_profile plot throws the "non-numeric argument to binary operator" error. The sar_risk_level() value in overall_risk_profile is dependent on a calculation (sar_risk_level_est) which depends on the number of inputs. I want this value (sar_risk) to be initizialied to zero and updated everytime the action button is pressed.
Great looking app. I think it is just a typo. The code has 25*input*members instead of 25*input$members on line 151.
Let's consider my very basic application :
Created by code :
Server
library(shiny) # Load shiny package
start <- as.Date("2013-01-01")
end <- as.Date("2016-10-01")
#Apple stock
getSymbols("AAPL", src = "yahoo", from = start, to = end)
apple <- AAPL$AAPL.Close
#Gold
getSymbols('GOLD', src = 'yahoo', from = start, to = end)
gold <- GOLD$GOLD.Close
#S&P500
getSymbols('^GSPC', src = 'yahoo', from = start, to = end)
sp <- as.numeric(`GSPC`[,4])
#Microsoft
getSymbols('MSFT', src = 'yahoo', from = start, to = end)
msft <- MSFT$MSFT.Close
stock.frame <- data.frame(apple, gold, msft, sp)
colnames(stock.frame) <- c('apple', 'gold', 'msft', 'sp')
shinyServer(
function(input, output) {
output$myhist <- renderPlot({
colm <- as.numeric(input$var)
hist(stock.frame[, colm], col = input$colour, xlim = c(min(stock.frame[, colm]), max(stock.frame[, colm])), main = "Histogram of stock dataset", breaks = seq(min(stock.frame[, colm]), max(stock.frame[, colm]), l = input$bin + 1), xlab = names(stock.frame[colm]))
})
}
)
UI
library(shiny) # load the shiny package
# Define UI for application
shinyUI(fluidPage(
# Header or title Panel
titlePanel(h4('Demostration of the renderPlot() - A Histogram with stock dataset', align = "center")),
# Sidebar panel
sidebarPanel(
selectInput("var", label = "1. Select the quantitative Variable",
choices = c("Apple" = 1, "Gold" = 2, "S&P" = 3, "BTC"=4),
selected = 3),
sliderInput("bin", "2. Select the number of histogram BINs by using the slider below", min=5, max=50, value=15),
radioButtons("colour", label = "3. Select the color of histogram",
choices = c("Green", "Red",
"Yellow"), selected = "Green")
),
# Main Panel
mainPanel(
textOutput("text1"),
textOutput("text2"),
textOutput("text3"),
plotOutput("myhist")
)
)
)
I want to have another sidebarPanel (analogous to '1. Select the quantitative Variable') in which I can specify if I want 'Histogram' or 'nothing'. If histogram was choosed then I should have same thing as above. When "nothing' was choosed I should see blank page. Do you know how it can be performed ?
EDIT
I added radiobutton as #r2evans suggested. It now look's in the way following :
shinyUI(fluidPage(
radioButtons("rb", "Plot type:", choiceNames = c("Histogram", "Nothing")),
# Header or title Panel
titlePanel(h4('Demostration of the renderPlot() - A Histogram with stock dataset', align = "center")),
# Sidebar panel
sidebarPanel(
selectInput("var", label = "1. Select the quantitative Variable",
choices = c("Apple" = 1, "Gold" = 2, "S&P" = 3, "BTC"=4),
selected = 3),
sliderInput("bin", "2. Select the number of histogram BINs by using the slider below", min=5, max=50, value=15),
radioButtons("colour", label = "3. Select the color of histogram",
choices = c("Green", "Red",
"Yellow"), selected = "Green")
),
# Main Panel
mainPanel(
textOutput("text1"),
textOutput("text2"),
textOutput("text3"),
plotOutput("myhist")
)
)
)
However after running 'Run App' i see error :
Error in normalizeChoicesArgs: Please specify a non-empty vector for `choices` (or, alternatively, for both `choiceNames` AND `choiceValues`).
81: stop
80: normalizeChoicesArgs
79: radioButtons
Have I done something wrong ?
Perhaps you are looking for a solution like this
library(shiny)
library(quantmod)
start <- as.Date("2013-01-01")
end <- as.Date("2016-10-01")
#Apple stock
getSymbols("AAPL", src = "yahoo", from = start, to = end)
apple <- AAPL$AAPL.Close
#Gold
getSymbols('GOLD', src = 'yahoo', from = start, to = end)
gold <- GOLD$GOLD.Close
#S&P500
getSymbols('^GSPC', src = 'yahoo', from = start, to = end)
sp <- as.numeric(`GSPC`[,4])
#Microsoft
getSymbols('MSFT', src = 'yahoo', from = start, to = end)
msft <- MSFT$MSFT.Close
stock.frame <- data.frame(apple, gold, msft, sp)
colnames(stock.frame) <- c('apple', 'gold', 'msft', 'sp')
cmat <- cor(stock.frame)
### plot_ly(z = cmat, type = "heatmap")
### Define UI for application
ui <- fluidPage(
# Header or title Panel
titlePanel(h4('Demostration of the renderPlot() - A Histogram with stock dataset', align = "center")),
# Sidebar panel
sidebarPanel(
selectInput("var", label = "1. Select the quantitative Variable",
choices = c("Apple" = 1, "Gold" = 2, "S&P" = 3, "BTC"=4),
selected = 3),
sliderInput("bin", "2. Select the number of histogram BINs by using the slider below", min=5, max=50, value=15),
radioButtons("graphtype", label = "Select Type of Graph",
choices = c("Heatmap", "Histogram", "DataTable"), selected = "Heatmap"),
conditionalPanel(
condition = "input.graphtype == 'Histogram' ",
radioButtons("colour", label = "3. Select the color of histogram",
choices = c("Green", "Red", "Yellow"), selected = "Green")
)
),
# Main Panel
mainPanel(
textOutput("text1"),
textOutput("text2"),
textOutput("text3"),
conditionalPanel(
condition = "input.graphtype == 'Heatmap' ", plotlyOutput("heatmap", width = "100%", height="600px")
),
conditionalPanel(
condition = "input.graphtype == 'Histogram' ", plotOutput("myhist")
),
conditionalPanel(
condition = "input.graphtype == 'DataTable' ", DTOutput("tb1")
)
)
)
server <- function(input, output) {
output$myhist <- renderPlot({
colm <- as.numeric(input$var)
hist(stock.frame[, colm], col = input$colour, xlim = c(min(stock.frame[, colm]), max(stock.frame[, colm])), main = "Histogram of stock dataset", breaks = seq(min(stock.frame[, colm]), max(stock.frame[, colm]), l = input$bin + 1), xlab = names(stock.frame[colm]))
})
output$heatmap <- renderPlotly({plot_ly(x = colnames(stock.frame), y = colnames(stock.frame), z = cmat, type = "heatmap") %>%
layout(
xaxis = list(title=colnames(stock.frame)),
yaxis = list(title="ts")
)
})
output$tb1 <- renderDT(stock.frame)
}
# Run the application
shinyApp(ui = ui, server = server)
I am trying to insert an action button that would delete the last input/row of data (enterer by clicking), but I want to be able to keep entering data by clicking afterward. I summary I have a dataframe which is accumulating data every time I click on the plot, I want an action button that remove the last click and data that goes with it in the dataframe, but I want to be able to keep going afterward. I try a simple solution because I feel it should be simple, but I cannot get it. Thank you very much for your help.
library(shiny)
library(ggplot2)
ui <- fluidPage(
titlePanel("team"),
sidebarPanel(
textInput(inputId = "date",
label = "Date",
value = "yyyy/mm/dd"),
textInput(inputId = "team",
label = "Team Name",
value = "Team Name"),
textInput(inputId = "pnumber",
label = "Player Number",
value = "#"),
selectInput("shot", "shot type:",
list(`Shot Type` = list("wrist shot", "slap shot", "snap shot"))),
selectInput("situation", "scoring opportunity:",
list(`Green` = list("Double cross", "dot line pass"),
`Red` = list("clear", "wrap"))),
actionButton("reset", "Clear")),
mainPanel(tabsetPanel(
tabPanel("Track", plotOutput(outputId = "hockeyplot", click = "plot_click", dblclick = "plot_dblclick")),
tabPanel("Data", tableOutput(outputId = "table"), downloadLink("downloadData", "Download")),
tabPanel("Chart", plotOutput(outputId = "chart")))))
server <- function(input, output){
rv <- reactiveValues(
df = data.frame(
x = numeric(),
y = numeric(),
Date = as.Date(character()),
Team = character(),
Player = character(),
ShotType = character(),
Situation = character(),
Type = factor()
)
)
output$hockeyplot = renderPlot({
ggplot(rv$df,
aes(x = x, y = y)) + coord_flip() + lims(x = c(0, 100), y = c(42.5, -42.5))+ geom_point( aes(colour = factor(Type)), size = 5 ) + theme(legend.position = "none")})
observeEvent(input$plot_click, {
rv$df <- rbind(rv$df, data.frame(
x = input$plot_click$y,
y = input$plot_click$x,
Date = input$date,
Team = input$team,
Player = input$pnumber,
ShotType = input$shot,
Situation = input$situation,
Type = "Shot"))
})
observeEvent(input$plot_dblclick, {
rv$df <- rbind(rv$df, data.frame(
x = input$plot_dblclick$y,
y = input$plot_dblclick$x,
Date = input$date,
Team = input$team,
Player = input$pnumber,
ShotType = input$shot,
Situation = input$situation,
Type = "Goal"))
})
observeEvent(input$reset,{
rv$df( rv$df()[-nrow(rv$df()),])
})
output$table<-renderTable({
rv$df
})
output$downloadData <- downloadHandler(
filename = function() {
paste("MHdata-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(rv$df, file)
}
)
}
shinyApp(ui = ui, server = server)
You mixed up some brackets when using reactiveValues. Basically, you can call and assign them without (.
library(shiny)
library(ggplot2)
ui <- fluidPage(
titlePanel("team"),
sidebarPanel(
textInput(inputId = "date",
label = "Date",
value = "yyyy/mm/dd"),
textInput(inputId = "team",
label = "Team Name",
value = "Team Name"),
textInput(inputId = "pnumber",
label = "Player Number",
value = "#"),
selectInput("shot", "shot type:",
list(`Shot Type` = list("wrist shot", "slap shot", "snap shot"))),
selectInput("situation", "scoring opportunity:",
list(`Green` = list("Double cross", "dot line pass"),
`Red` = list("clear", "wrap"))),
actionButton("reset", "Clear")),
mainPanel(tabsetPanel(
tabPanel("Track", plotOutput(outputId = "hockeyplot", click = "plot_click", dblclick = "plot_dblclick")),
tabPanel("Data", tableOutput(outputId = "table"), downloadLink("downloadData", "Download")),
tabPanel("Chart", plotOutput(outputId = "chart")))))
server <- function(input, output){
rv <- reactiveValues(
df = data.frame(
x = numeric(),
y = numeric(),
Date = as.Date(character()),
Team = character(),
Player = character(),
ShotType = character(),
Situation = character(),
Type = factor()
)
)
output$hockeyplot = renderPlot({
ggplot(rv$df,
aes(x = x, y = y)) + coord_flip() + lims(x = c(0, 100), y = c(42.5, -42.5))+ geom_point( aes(colour = factor(Type)), size = 5 ) + theme(legend.position = "none")})
observeEvent(input$plot_click, {
rv$df <- rbind(rv$df, data.frame(
x = input$plot_click$y,
y = input$plot_click$x,
Date = input$date,
Team = input$team,
Player = input$pnumber,
ShotType = input$shot,
Situation = input$situation,
Type = "Shot"))
})
observeEvent(input$plot_dblclick, {
rv$df <- rbind(rv$df, data.frame(
x = input$plot_dblclick$y,
y = input$plot_dblclick$x,
Date = input$date,
Team = input$team,
Player = input$pnumber,
ShotType = input$shot,
Situation = input$situation,
Type = "Goal"))
})
# NO BRACKETS NEEDED
observeEvent(input$reset,{
rv$df <- rv$df[-nrow(rv$df),]
})
output$table<-renderTable({
rv$df
})
output$downloadData <- downloadHandler(
filename = function() {
paste("MHdata-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(rv$df, file)
}
)
}
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)
I am trying to make reactive elements in my shiny app using RStudio. I want the radio buttons to appear or disappear depending upon a checkbox. Then I am gathering the inputs from the elements displayed to generate two graphs. The problem is that the elements in UI are not reactive. Below is the coding I used.
library(shiny)
library(AER)
library(ggplot2)
library(plotly)
CreditCard <- read.csv("https://gist.githubusercontent.com/anonymous/3ffc253260bae6894c00edb2062729d6/raw/6c08d02eaba4b1691212fd518f2079ef2c112a20/Credit_Card.csv")
key <- read.csv("https://gist.githubusercontent.com/anonymous/9a8c05eb2202d79b03b187117e6fe709/raw/beddca49b669fe5ff27ce7dd1c7bcbe1c4660327/key.csv")
df_cc = CreditCard[sample(nrow(CreditCard), 500), ]
ui <- fluidPage(
title = "Final Project",
sidebarLayout(
sidebarPanel(
conditionalPanel(
'input.tabs === "Graphs"',
checkboxInput("checkbox_facet", label = "Show Facet", value = TRUE),
tags$div(id = 'placeholder'),
selectInput("select_y", label = h4("Select Y-Axis"),
choices = list("Age" = "age", "Income" = "income", "Share" = "share", "Expenditure" = "expenditure", "Months" = "months", "MajorCards" = "majorcards", "Active" = "active"), selected = "active"),
selectInput("select_x", label = h4("Select X-Axis"),
choices = list("Age" = "age", "Income" = "income", "Share" = "share", "Expenditure" = "expenditure", "Months" = "months", "MajorCards" = "majorcards", "Active" = "active"), selected = "income")
) # end conditionalPanel for graphs
), #end sidebarPanel
mainPanel(
tabsetPanel(
id = 'tabs',
tabPanel("Graphs",
plotlyOutput(outputId = "exp"),
plotlyOutput(outputId = "reg"),
uiOutput(outputId = "facet")
) #Graphs
) # end tabsetPanel
) # end mainPanel
) # end sidebarLayout
) # end fluid page
server <- function(input, output) {
observeEvent(input$checkbox_facet, { if (input$checkbox_facet == TRUE) { # radio buttons for facet options show, and graph be made accordingly.
output$facet <- eventReactive(input$checkbox_facet, { insertUI( selector = "#placeholder",
ui = radioButtons("radio_facet", label = h4("Choose Facet Variable"),
choices = list("Card" = "card", "Reports" = "reports", "Owner" = "owner", "SelfEmployed" = "selfemp", "Dependents" = "dependents"), selected = "owner")
) })
output$exp <- eventReactive(input$select_x, { renderPlotly({
ggplotly(
ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) + geom_point(shape=1) +
facet_wrap(~get(input$radio_facet), labeller = label_both) +
labs(title = "Exploratory Plot", x = input$select_x, y = input$select_y)
)
})
})
output$reg <- eventReactive(input$select_x, { renderPlotly({
ggplotly(
ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) + geom_point(shape=1) +
geom_smooth(method = "glm", family = "poisson", se = FALSE) +
facet_wrap(~get(input$radio_facet), labeller = label_both) +
labs(title = "Poisson Regression", x = input$select_x, y = input$select_y)
)
})
})
}
else { # radio buttons disappear and graph is without facets
output$facet <- eventReactive(input$checkbox_facet, { removeUI(selector = 'div:has(> #radio_facet)', immediate = TRUE) })
output$exp <- eventReactive(input$select_x, { renderPlotly({
ggplotly(
ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) + geom_point(shape=1) +
labs(title = "Exploratory Plot", x = input$select_x, y = input$select_y)
)
})
})
output$reg <- eventReactive(input$select_x, { renderPlotly({
ggplotly(
ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) + geom_point(shape=1) +
geom_smooth(method = "glm", family = "poisson", se = FALSE) +
labs(title = "Poisson Regression", x = input$select_x, y = input$select_y)
)
})
})
}
}) # end observeEvent for graphs
}
shinyApp(ui, server)
You're just overcomplicating things.
In your code, you have reactive expressions, that reactively assign other reactive expressions. So you always fight with a double layer of reactivity.
I don't know if you noticed, but you also delete the placeholder div the first time the checkbox is unchecked. You maybe did this on purpose, because otherwise the radio buttons will always be there. Because overwriting the output$facet will not delete any reacting expressions. And your reactive logic itself does not contain the state of input$checkbox_facet. So you are always fighting with reactive expressions, that you reassign and where you have no control over how they are executed.
What I recommend is, to clean up your code. Pick each output element by itself and define what reactions you really want to happen. And then define a fixed behaviour, that reflects that.
Also, be aware that render functions are reactive environments by default.
Below is a refactoring that works:
library(shiny)
library(AER)
library(ggplot2)
library(plotly)
CreditCard <- read.csv("https://gist.githubusercontent.com/anonymous/3ffc253260bae6894c00edb2062729d6/raw/6c08d02eaba4b1691212fd518f2079ef2c112a20/Credit_Card.csv")
key <- read.csv("https://gist.githubusercontent.com/anonymous/9a8c05eb2202d79b03b187117e6fe709/raw/beddca49b669fe5ff27ce7dd1c7bcbe1c4660327/key.csv")
df_cc = CreditCard[sample(nrow(CreditCard), 500), ]
ui <- fluidPage(
title = "Final Project",
sidebarLayout(
sidebarPanel(
conditionalPanel(
'input.tabs === "Graphs"',
checkboxInput("checkbox_facet", label = "Show Facet", value = TRUE),
uiOutput("facets"),
selectInput("select_y", label = h4("Select Y-Axis"),
choices = list("Age" = "age", "Income" = "income", "Share" = "share", "Expenditure" = "expenditure", "Months" = "months", "MajorCards" = "majorcards", "Active" = "active"), selected = "active"),
selectInput("select_x", label = h4("Select X-Axis"),
choices = list("Age" = "age", "Income" = "income", "Share" = "share", "Expenditure" = "expenditure", "Months" = "months", "MajorCards" = "majorcards", "Active" = "active"), selected = "income")
) # end conditionalPanel for graphs
), #end sidebarPanel
mainPanel(
tabsetPanel(
id = 'tabs',
tabPanel("Graphs",
plotlyOutput(outputId = "exp"),
plotlyOutput(outputId = "reg")
) #Graphs
) # end tabsetPanel
) # end mainPanel
) # end sidebarLayout
) # end fluid page
server <- function(input, output) {
output$facets <- renderUI({
if (input$checkbox_facet) {
radioButtons("radio_facet",
label = h4("Choose Facet Variable"),
choices = list("Card" = "card", "Reports" = "reports", "Owner" = "owner", "SelfEmployed" = "selfemp", "Dependents" = "dependents"),
selected = "owner"
)
}
})
output$exp <- renderPlotly({
g <- ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) +
geom_point(shape=1) +
labs(title = "Exploratory Plot", x = input$select_x, y = input$select_y)
if (input$checkbox_facet) {
g <- g + facet_wrap(~get(input$radio_facet), labeller = label_both)
}
ggplotly(g)
})
output$reg <- renderPlotly({
g <- ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) +
geom_point(shape=1) +
geom_smooth(method = "glm", family = "poisson", se = FALSE) +
labs(title = "Poisson Regression", x = input$select_x, y = input$select_y)
if (input$checkbox_facet) {
g <- g + facet_wrap(~get(input$radio_facet), labeller = label_both)
}
ggplotly(g)
})
}
shinyApp(ui, server)
To address the comment from Gregor de Cillia about conditional panels: You might not want to recreate the radio buttons every time the checkbox changes, since the options are in fact always the same. (And you might want to keep the state, i.e. which item was selected previously.) A conditionalPanel just hides the radio buttons and therefore cleans up your server code even more.
Example below:
library(shiny)
library(AER)
library(ggplot2)
library(plotly)
CreditCard <- read.csv("https://gist.githubusercontent.com/anonymous/3ffc253260bae6894c00edb2062729d6/raw/6c08d02eaba4b1691212fd518f2079ef2c112a20/Credit_Card.csv")
key <- read.csv("https://gist.githubusercontent.com/anonymous/9a8c05eb2202d79b03b187117e6fe709/raw/beddca49b669fe5ff27ce7dd1c7bcbe1c4660327/key.csv")
df_cc = CreditCard[sample(nrow(CreditCard), 500), ]
ui <- fluidPage(
title = "Final Project",
sidebarLayout(
sidebarPanel(
conditionalPanel(
'input.tabs === "Graphs"',
checkboxInput("checkbox_facet", label = "Show Facet", value = TRUE),
conditionalPanel('input.checkbox_facet',
radioButtons("radio_facet",
label = h4("Choose Facet Variable"),
choices = list("Card" = "card", "Reports" = "reports", "Owner" = "owner", "SelfEmployed" = "selfemp", "Dependents" = "dependents"),
selected = "owner"
)
),
selectInput("select_y", label = h4("Select Y-Axis"),
choices = list("Age" = "age", "Income" = "income", "Share" = "share", "Expenditure" = "expenditure", "Months" = "months", "MajorCards" = "majorcards", "Active" = "active"), selected = "active"),
selectInput("select_x", label = h4("Select X-Axis"),
choices = list("Age" = "age", "Income" = "income", "Share" = "share", "Expenditure" = "expenditure", "Months" = "months", "MajorCards" = "majorcards", "Active" = "active"), selected = "income")
) # end conditionalPanel for graphs
), #end sidebarPanel
mainPanel(
tabsetPanel(
id = 'tabs',
tabPanel("Graphs",
plotlyOutput(outputId = "exp"),
plotlyOutput(outputId = "reg")
) #Graphs
) # end tabsetPanel
) # end mainPanel
) # end sidebarLayout
) # end fluid page
server <- function(input, output) {
output$exp <- renderPlotly({
g <- ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) +
geom_point(shape=1) +
labs(title = "Exploratory Plot", x = input$select_x, y = input$select_y)
if (input$checkbox_facet) {
g <- g + facet_wrap(~get(input$radio_facet), labeller = label_both)
}
ggplotly(g)
})
output$reg <- renderPlotly({
g <- ggplot(df_cc, aes(x=get(input$select_x), y=get(input$select_y))) +
geom_point(shape=1) +
geom_smooth(method = "glm", family = "poisson", se = FALSE) +
labs(title = "Poisson Regression", x = input$select_x, y = input$select_y)
if (input$checkbox_facet) {
g <- g + facet_wrap(~get(input$radio_facet), labeller = label_both)
}
ggplotly(g)
})
}
shinyApp(ui, server)