ggplot dateRangeInput in Rshiny - r

I am trying to make my line graph change based on the users input in the dateRangeInput widget in Rshiny. I have a column named SampleTime that has dates but every time I run the app I cannot seem to get the plot to change. I am obviously not linking this together correctly. Can anyone provide any input to this problem? Below is my code in app code in R.
library(tidyverse)
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("TPO Data Over Time by Valve ID and Product Type"),
# Sidebar
sidebarLayout(
position = "left",
sidebarPanel(
selectInput(inputId = "valves",
label = strong("Valve ID"),
choices = unique(cTPO$ValveID),
selected = "1"),
selectInput(inputId = "products",
label = strong("Product Type"),
choices = unique(cTPO$Product),
selected = "12OZ CAN"),
dateRangeInput(inputId = "calendar",
label = 'Date range input: mm-dd-yyyy',
format = "mm-dd-yyyy",
start = NULL, end = NULL)),
mainPanel(
plotOutput("TPOPlot"))))
# Define server logic required to draw a line plot
server <- function(input, output) {
output$TPOPlot <- renderPlot({
## Read cTPO.csv and assign
cTPO <- read_csv("cTPO.csv")
## Get date from data
cTPO$SampleTime <- as.Date(cTPO$SampleTime, "%m/%d/%Y")
## Create point plot of TPO by valve number and product type
cTPO %>%
select(
ValveID,
BrandName,
Product,
TPOvalue,
CO2value,
LogIDKey,
SampleTime) %>%
filter_all(all_vars(!is.na(.)))
## Create line plot of TPO data
cTPO %>%
filter (ValveID == input$valves, Product == input$products) %>%
ggplot(aes (x = SampleTime, y = TPOvalue)) +
geom_line() +
labs (x = "Sample Date", y ="TPO Value") +
theme_bw()
})
}

Related

How to create interactive x y axes for bar chart using R Shiny

I'm trying to build a simply R Shiny app that displays a bar chart with both axes as interactive elements. I'll demonstrate what I've done with the built in flights dataset.
I'm able to build a static bar chart, but only get errors when interactive. I've tried colnames(data), names(data), and aes_string in the server function. I think the issue is that in the ggplot aes the x label is read in as string but after_stat(count) isn't. Unfortunately I can't find any similar examples on the internet.
Any ideas how to resolve this? Thanks
# load packages
library(dplyr)
library(tidyr)
library(shiny)
library(ggplot2)
# data
library(nycflights13)
data = flights %>% select(carrier, origin, dest)
# desired bar chart
ggplot(data, aes(x=carrier, y=after_stat(count))) +
geom_bar(aes(fill = origin), position = "dodge")
ui <- fluidPage(
# sidebar
sidebarLayout(
selectInput(inputId = "xvar",
label = "X-axis variable",
choices = colnames(data),
#choices = names(data),
selected = "carrier"
),
selectInput(inputId = "yvar",
label = "Y-axis variable",
choices = colnames(data),
#choices = names(data),
selected = "origin"
)
),
# main plot
mainPanel(
plotOutput("id_main_plot")
)
)
# server logic to draw histogram
server <- function(input, output) {
output$id_main_plot <- renderPlot({
# Render bar chart
ggplot(data = data,
aes(x = input$xvar,
y = after_stat(count)
)
) +
geom_bar(aes(fill = input$yvar),
position = "dodge"
)
})
}
# create Shiny app
shinyApp(ui, server)
The issue is that input$xvar and input$yvar are just character strings. When you map these on aesehtics in ggplot2 they will be treated as constants. To tell ggplot2 that these character strings are names of columns in your dataset you could use the so-called .data pronoun. For more on the .data pro-noun in the context of ggplot2 and shiny see e.g. this example in Mastering Shiny
library(shiny)
library(dplyr)
library(ggplot2)
library(nycflights13)
data <- flights %>% select(carrier, origin, dest)
ui <- fluidPage(
sidebarLayout(
selectInput(
inputId = "xvar",
label = "X-axis variable",
choices = colnames(data),
selected = "carrier"
),
selectInput(
inputId = "yvar",
label = "Y-axis variable",
choices = colnames(data),
selected = "origin"
)
),
mainPanel(
plotOutput("id_main_plot")
)
)
server <- function(input, output) {
output$id_main_plot <- renderPlot({
ggplot(
data = data,
aes(
x = .data[[input$xvar]],
y = after_stat(count)
)
) +
geom_bar(aes(fill = .data[[input$yvar]]),
position = "dodge"
)
})
}
# create Shiny app
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:3217

I've added a date range slider to my plotly scatterplot in shiny, but how do I get the data to change according to the widget?

I am trying to have the selectinput widget "Years - Slide" change the data used by the graph to the specific date range shown. I was able to connect the axis options in the ui code to the server code since the graph changes, but I do not know how to do the same to the date range widget.
I am trying to use a selectInput widget instead of a date input widget since I only have the year to work with.
Would anyone know how to resolve this?
I was expecting to see the graph according to the changes in the widget, but that is not working.
functional code without selectinput in the server code
library(gapminder)
gm <- gapminder
library(shiny)
library(plotly)
library(tibble)
library(tidyverse)
library(tidyr)
library(readr)
library(dplyr)
library(ggplot2)
# set working directory
setwd("~/BDSWD")
# Define UI ----
ui <- fluidPage(
column(3,offset = 4, titlePanel("Explore Gapminder Data with Shiny")),
headerPanel('Graphs'),
mainPanel(
plotlyOutput('plot')
),
sidebarPanel(
#variable selection for x-axis
selectInput(inputId ='xvrbl', #The input slot that will be used to access the value.
label = 'X-Axis Variable', #Display label for the control, or NULL for no label.
choices = colnames(gm), #List of values to select from
selected = 'lifeExp'
),
#variable selection for y-axis
selectInput(inputId ='yvrbl', #The input slot that will be used to access the value.
label = 'Y-Axis Variable', #Display label for the control, or NULL for no label.
choices = colnames(gm), #List of values to select from
selected = 'gdpPercap'
),
#date range - slider
sliderInput(inputId = "time",
label = "Years - Slide",
min = min(gm$year),
max = max(gm$year),
step = 5,
value = c(min(gm$year),max(gm$year))),
)
)
server <- function(input, output) {
x <- reactive({
pull(gm[,input$xvrbl])
})
y <- reactive({
pull(gm[,input$yvrbl]) #pull used to turn tibble into vctr bc plotly only takes vctrs
})
output$plot <- renderPlotly(
plot1 <- plot_ly(
x = x(),
y = y(),
type = 'scatter',
mode = 'markers',
color = gm$continent,
data <- subset(gm,
continent %in% input$continents &
year >= input$years[1] & year <= input$years[2])
)
)
}
# Run the app
shinyApp(ui = ui, server = server)
code with my attempt to connect selectInput to the server code (not working)
Unfortunately you code was not working. As first step I added a reactive to create the filtered dataset based on the user input. Second step was to add the selectInput to select the year to be plotted.
library(gapminder)
library(shiny)
library(plotly)
library(tidyverse)
gm <- gapminder
# Define UI ----
ui <- fluidPage(
column(3, offset = 4, titlePanel("Explore Gapminder Data with Shiny")),
headerPanel("Graphs"),
mainPanel(
plotlyOutput("plot")
),
sidebarPanel(
# variable selection for x-axis
selectInput(
inputId = "xvrbl", # The input slot that will be used to access the value.
label = "X-Axis Variable", # Display label for the control, or NULL for no label.
choices = colnames(gm), # List of values to select from
selected = "lifeExp"
),
# variable selection for y-axis
selectInput(
inputId = "yvrbl", # The input slot that will be used to access the value.
label = "Y-Axis Variable", # Display label for the control, or NULL for no label.
choices = colnames(gm), # List of values to select from
selected = "gdpPercap"
),
# date range - slider
selectInput(
inputId = "time",
label = "Years - Slide",
choices = unique(gm$year),
selected = max(gm$year)
)
)
)
server <- function(input, output) {
x <- reactive({
dat()[[input$xvrbl]]
})
y <- reactive({
dat()[[input$yvrbl]]
})
dat <- reactive({
subset(gm, year %in% input$time)
})
output$plot <- renderPlotly({
plot_ly(
x = x(),
y = y(),
type = "scatter",
mode = "markers",
color = dat()$continent
)
})
}
# Run the app
shinyApp(ui = ui, server = server)
#>
#> Listening on http://127.0.0.1:5182

Choosefile widget: "Error in FUN: object 'Type' not found"

I am building a shiny app that would allow me to select a data file using a widget "choose file" and "select file" as well as plotting a bar graph using geom_bar object of the library ggplot2. The plot consists of a bar graph representing the revenue ("Revenue") per type of operation ("Type") and has a different colour of the bar for each type.
When I run the app I get the following error : Error in FUN: object 'Type' not found.
I have changed aes by aes_string but it doesn't change anything. I have also tried to add inherit.aes = FALSE in the geom_bar object. I made sure the data I use is saved as data frame.
library(shiny)
library(ggplot2)
library(dplyr)
#user interface
ui <- fluidPage(
headerPanel(title = "Shiny File Upload"),
sidebarLayout(
sidebarPanel(
fileInput(inputId = "file",
label = "Upload the file",
multiple = TRUE),
checkboxInput(inputId = "header", label = "Header"),
radioButtons("sep","Seperator", choices = c(Comma=",", Period = ".", Semicolon = ";")),
# Select variable for y-axis
selectInput(inputId = "y",
label = "Revenue:",
choices = "Revenue",
selected = ""),
# Select variable for x-axis
selectInput(inputId = "x",
label = "X-axis:",
choices = "Type",
selected = ""),
# Select variable for color
selectInput(inputId = "z",
label = "Color by:",
choices = "Type",
selected = "")
),
# Outputs
mainPanel(
uiOutput("input_file"),
plotOutput(outputId = "Barplot")
)
)
)
# Define server function required to create the scatterplot
server <- function(input, output) {
#Dispays the content of the input$file dataframe
output$filedf <- renderTable({
if(is.null(input$file)){return()}
input$file
})
output$filedf2 <- renderTable({
if(is.null(input$file)){return()}
input$file$datapath
})
#Side bar select input widget coming through render UI()
output$selectfile <- renderUI({
if(is.null(input$file)){return()}
list(hr(),
helpText("Select the files for which you need to see data and summary stats"),
selectInput("Select", "Select", choices=input$file$name)
)
})
# Create the scatterplot object the plotOutput function is expecting
output$Barplot <- renderPlot({
ggplot(data = input$file, aes_string(x = input$x , y = input$y, fill = input$x)) + geom_bar( stat ="identity") + coord_flip()
})
}
shinyApp(ui = ui, server = server)
I expect to have a bar plot with revenues bar for the 14 type of operation, with bar color differing depending on the observation.
I expect to be able to select the data I want and get this bar plot for this dataset.

How to render a line plot that changes based on my inputs and shows a color line for each line

I created this shiny app and now I would like to add a line plot to the app.
The data is in a .csv file
I am able to generate data in a table format and I want to include a line plot that is reactive to my inputs.
shelter <- read.csv("shelter.csv",stringsAsFactors=FALSE)
Shelter,Year,Cat,Dog,Rabbit,Other
Pitt,2013,31,22,19,23
Pitt,2014,23,54,65,15
Pitt,2015,56,62,28,24
Pitt,2016,65,23,33,32
Pitt,2017,49,74,36,18
Phila,2013,11,32,26,35
Phila,2014,66,65,145,27
Phila,2015,69,64,121,18
Phila,2016,84,81,195,9
Phila,2017,79,35,96,7
Allen,2013,161,36,26,11
Allen,2014,24,97,84,21
Allen,2015,101,74,24,19
Allen,2016,254,74,112,3
Allen,2017,95,63,247,22
Harris,2013,78,60,168,17
Harris,2014,29,85,39,16
Harris,2015,201,75,245,7
Harris,2016,27,55,88,9
Harris,2017,65,46,71,11
Read,2013,94,95,68,20
Read,2014,98,91,94,19
Read,2015,125,73,203,21
Read,2016,87,101,119,5
Read,2017,148,98,149,6
York,2013,56,73,65,14
York,2014,61,74,95,7
York,2015,99,89,84,2
York,2016,121,120,84,11
York,2017,67,68,85,2
#Code:
library(shiny)
ui <- fluidPage(
titlePanel('Animal Shelter Data:'),
sidebarLayout(
sidebarPanel(
selectInput("Shelter", label = h4("Select a Shelter:"),choices =shelter$Shelter),
checkboxGroupInput("Category", label = h4("Category"),
choices = list("Cat" , "Dog" , "Rabbit", "Other"),
selected = list("Cat" , "Dog" , "Rabbit", "Other")),
checkboxGroupInput("Year", label = h4("Select Year(s)"),
choices = unique(shelter$Year),
selected = list('2013', '2014', '2015', '2016','2017'))
),
mainPanel(
tableOutput("shelterdata"),
plotOutput("lineplot")
)
)
)
server <- function(input, output) {
output$shelterdata <- renderTable({
shelterfilter <- subset(shelter[shelter$Shelter == input$Shelter & shelter$Year %in% input$Year,])
shelterfilter[c('Shelter', 'Year', input$Category)]
})
}
shinyApp(ui = ui, server = server)
I would like to render a line plot that changes based on my input$Shelter, input$Category, input$Year and shows a color line for each animal:
x-axis = Year
y-axis = number of animals
This answer requires the tidyr, magrittr and ggplot2 packages. This code can be placed inside the server function.
output$lineplot <- shiny::renderPlot({
shelterfilter <- subset(shelter[shelter$Shelter == input$Shelter & shelter$Year %in% input$Year,]) %>%
tidyr::gather(key = "Animal",value = "Animal.Qty",-Shelter,-Year)
ggplot(data = shelterfilter,aes(x = Year,y=Animal.Qty,color=Animal)) +
geom_line()
})

Shiny radio buttons - Aesthetics must be either length 1 or the same as the data

Hello
I'm having some trouble with an error 'aesthetics must be either length 1 or the same as the data' for a reactive ggplot in a shiny.
First, a little bit of info on the structure of the data:
I'm using a big dataset, with lots of variables. As seen in the code below, I've built a reactive dataset to first filter by geography (higher and lower levels) and service type. The user then has the option to choose a Y variable using a radioButton input. In the example given below, the Services variable is the total number of commercial services being run by brands in the area, whereas the Brand variable is a list of Brands operating in that locality. As an example:
"Brand" "Services" "Rating"
A 25 Good
B 12 Good
C 45 Poor
... ... ...
I'm want my Y variable made changeable according to a radioButton input. There are two possible variables, one is numerical (i.e. 'Services' or number of services) and the other is categorical (i.e. commercial brands). Both vectors are the same length. In sum, I want the Y axis to show a count of either variables (i.e. No. Services or No. Brands).
However, when I change the radioButton selection, the visual does not update and (as seen in the images 1 and 2 below) the Y axis does not format properly.
What am I missing?
Image 1: Selected Services
Image 2: Selected Brands
UI
ui <- fluidPage(
titlePanel("Test App"),
sidebarLayout(
sidebarPanel(id = "sidebar",
uiOutput("geography1"),
uiOutput("geography2"),
uiOutput("service"),
radioButtons("y", "Choose Y variable",
c("Services",
"Brands"),
selected = "Services")
)
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Visual", plotOutput("plot", height = "500px")),
tabPanel("Underlying data", dataTableOutput("table"))
)
)
)
)
)
Server
server <- function(input, output) {
output$geography1 = renderUI({
selectInput(inputId = "geog1",
label = "Select geography (higher):",
choices = as.character(unique(Test$Geog1)),
selected = "Region")
})
datasub <- reactive({
req(input$geog1)
filter(Test, Geog1 %in% input$geog1)
})
output$geography2 = renderUI({
selectInput(inputId = "geog2",
label = "Select geography (lower):",
choices = unique(datasub()[,"Geog2"]),
selected = unique(datasub()[,"Geog2"])[1])
})
datasub2 <- reactive({
req(input$geog2)
filter(datasub(), Geog2 %in% input$geog2)
})
output$service = renderUI({
selectInput(inputId = "service",
label = "Select Service Type:",
choices = unique(datasub2()[,"Sub_type"]),
selected = unique(datasub2()[,"Sub_type"])[1])
})
datasub3 <- reactive({
req(input$geog2)
filter(datasub2(), Sub_type %in% input$service)
})
y <- switch(input$y,
"Services" = datasub3()$Services,
"Brands" = datasub3()$Brands)
# Plot
output$plot = renderPlot({
ggplot(datasub3(), aes(x = Overall_rating, y = input$y, fill = Overall_rating))+
geom_bar(stat = "identity")+
scale_fill_manual(name = "Overall Service Rating", values = colours)
})
# Generate an data table view of the data ----
output$table <- renderDataTable({
datasub3()[,1:9]
})
shinyApp(ui, server)
Image 3: Example of Desired Outcome
The problem was switch, which should define as below inside a reactive expression
y <- reactive(switch(input$y,
"Services" = datasub3()$Services,
"Brands" = datasub3()$Brands))
ggplot call will be
ggplot(datasub3(), aes(x = Overall_rating, y = y(), fill = Overall_rating))
Provided data set does not include Sub_type variable, hence I work with datasub2(). But if you counter any issues let me know.
Update
ggplot(datasub3(), aes(x = Overall_rating, y =y(), fill = Overall_rating))+
geom_bar(stat = "identity") +
scale_fill_manual(name = "Overall Service Rating", values = colours) +
geom_text(aes(label=Services), angle=00, hjust= 0.5, vjust=-1, cex=5)

Resources