Invalid input: date_trans works with objects of class Date only - r

Implementing this with ggplot2 and shiny by having two input selections for the date ranges and have the plot adjust the x(date values) adjust accordingly, however, I get this error below:
Invalid input: date_trans works with objects of class Date only
How can I resolve this? Here is my code below:
library(shiny)
library(ggplot2)
library(dplyr)
data <- read.csv("C:/Users/user/Documents/R/R-3.3.1/R CODE/MyData2.csv", header = TRUE) # reading .csv
newdata <- as.data.frame(data) # converting csv to DF
newdata$event_date <- as.factor(newdata$event_date)
str(newdata)
ui <- fluidPage(
selectInput("select", label = h3("Select Model"),
choices = list("Toyota Camry", "Nissan Altima")),
dateInput("strtdate", "Select start date:"),
dateInput("enddate", "Select end date:"),
plotOutput("hist")
)
server <- function(input, output) {
output$hist <- renderPlot({
df <- newdata %>% select(event_date,PlatformName,total_events) %>% filter(PlatformName == input$select) %>% group_by(event_date, PlatformName) %>% summarize(total_events = sum(total_events))
gg <- ggplot(df, aes(x= event_date, y = total_events, group =PlatformName)) +
geom_line(aes(color = PlatformName)) +
labs(title="Total Events vs. Time", x="Event Dates", y="Total Events") +
aes(xmin = input$strtdate,
xmax = input$enddate) +
theme(plot.title=element_text(size=20, face="bold", hjust = 0.5),
axis.text.x=element_text(size=10, angle=90,hjust=1,vjust=0.5),
axis.text.y=element_text(size=5),
axis.title.x=element_text(size=10),
axis.title.y=element_text(size=10))
print(gg)
})
}
shinyApp(ui = ui, server = server)

Solved the issue. Just needed to convert the specific date column in a date format.
Via:
newdata$event_date <- as.Date(newdata$event_date)
Thus, new code:
library(shiny)
library(ggplot2)
library(dplyr)
data <- read.csv("C:/Users/user/Documents/R/R-3.3.1/R CODE/MyData2.csv", header = TRUE) # reading .csv
newdata <- as.data.frame(data) # converting csv to DF
newdata$event_date <- as.factor(newdata$event_date) #CODE IMPLEMENTAITON
str(newdata)
ui <- fluidPage(
selectInput("select", label = h3("Select Model"),
choices = list("Toyota Camry", "Nissan Altima")),
dateInput("strtdate", "Select start date:"),
dateInput("enddate", "Select end date:"),
plotOutput("hist")
)
server <- function(input, output) {
output$hist <- renderPlot({
df <- newdata %>% select(event_date,PlatformName,total_events) %>% filter(PlatformName == input$select) %>% group_by(event_date, PlatformName) %>% summarize(total_events = sum(total_events))
gg <- ggplot(df, aes(x= event_date, y = total_events, group =PlatformName)) +
geom_line(aes(color = PlatformName)) +
labs(title="Total Events vs. Time", x="Event Dates", y="Total Events") +
aes(xmin = input$strtdate,
xmax = input$enddate) +
theme(plot.title=element_text(size=20, face="bold", hjust = 0.5),
axis.text.x=element_text(size=10, angle=90,hjust=1,vjust=0.5),
axis.text.y=element_text(size=5),
axis.title.x=element_text(size=10),
axis.title.y=element_text(size=10))
print(gg)
})
}
shinyApp(ui = ui, server = server)

Related

How to add a date range to ggplot in Rshiny?

I am making a shiny app to generate stock price plots. I want to generate plots given a certain date range, but I get the error "argument 1 is not a vector" whenever I try to adjust the dates. If I remove the "daterangeinput" part from my app, everything works fine. I have attached my code + data.
Run the section below to get the data.
library(tidyquant)
library(tidyverse)
library(shiny)
library(shinyWidgets)
library(shinythemes)
library(plotly)
sp500_names <- tq_index("SP500") %>%
slice_head(n = 10) %>%
select(symbol, company)
tickers <- sp500_names[,1]
prices <- tq_get(tickers,
get = "stock.prices",
from = today() - months(24),
to = today(),
complete_cases = F) %>%
select(symbol, date, close)
Code for shiny app:
ui <- fluidPage(
# Title
titlePanel("Stock Price Visualization and Forecasting"),
# Sidebar
sidebarLayout(
sidebarPanel(width = 3,
pickerInput(
inputId = "stocks",
label = h4("Pick a stock"),
choices = tickers$symbol,
selected = tickers,
options = list(`actions-box` = TRUE),
multiple = T),
# Date input
dateRangeInput("daterange", "Pick a Time Period",
# value = today(),
min = today() - months(23),
max = today())),
# Plot results
mainPanel(
plotlyOutput("plot",height=600)
)
)
)
server <- function(input, output, session) {
# Server logic based on user inputs
observeEvent(input$stocks,{
prices <- prices %>%
dplyr::filter(symbol %in% input$stocks) %>%
filter(date > input$daterange[1] & date <= input$daterange[2])
# Create plot
output$plot <- renderPlotly({
print(
ggplotly(prices %>%
ggplot(aes(date, close, color = symbol)) +
geom_line(size = 1, alpha = 0.9)+
theme_minimal(base_size=16) +
theme(axis.title=element_blank(),
plot.background = element_rect(fill = "white"),
panel.background = element_rect(fill="grey"),
panel.grid = element_blank(),
legend.text = element_text(colour="black"))
)
)
})
})
}
shinyApp(ui, server)
The issue is that you have not set any start and end dates for the date range and your apps does not take care of that. Hence an easy fix would be to simply set a default start and end date. Additionally IMHO I don't see any reason for an observeEvent. Instead I would suggest to use a reactive to filter your data based on user inputs, which could then be used for plotting:
library(tidyquant)
library(tidyverse)
library(shiny)
library(shinyWidgets)
library(shinythemes)
library(plotly)
ui <- fluidPage(
# Title
titlePanel("Stock Price Visualization and Forecasting"),
# Sidebar
sidebarLayout(
sidebarPanel(
width = 3,
pickerInput(
inputId = "stocks",
label = h4("Pick a stock"),
choices = tickers$symbol,
selected = tickers,
options = list(`actions-box` = TRUE),
multiple = T
),
# Date input
dateRangeInput("daterange", "Pick a Time Period",
# value = today(),
start = min(prices$date),
end = today(),
min = min(prices$date),
max = today()
)
),
# Plot results
mainPanel(
plotlyOutput("plot", height = 600)
)
)
)
server <- function(input, output, session) {
prices_filtered <- reactive({
req(input$stocks)
prices %>%
dplyr::filter(symbol %in% input$stocks) %>%
filter(date > input$daterange[1] & date <= input$daterange[2])
})
output$plot <- renderPlotly({
req(input$stocks)
g <- ggplot(prices_filtered(), aes(date, close, color = symbol)) +
geom_line(size = 1, alpha = 0.9) +
theme_minimal(base_size = 16) +
theme(
axis.title = element_blank(),
plot.background = element_rect(fill = "white"),
panel.background = element_rect(fill = "grey"),
panel.grid = element_blank(),
legend.text = element_text(colour = "black")
)
ggplotly(g)
})
}
shinyApp(ui, server)

Graph is not appearing

I am trying to create a graph where I am can view total flights by year, filtered by origin and its destination.
Picture1: What I envision VS Picture2: The result.
Problem 1: Graph unable to appear on shinyApp.
Problem 2: When the graph appears, the graph does not change even when I select a different Origin from the dropdown box
I am quite new to shiny, any help would be greatly appreciated! The data I am using is from Harvard database- data expo 2009, Airline on time data.
library(DBI)
library(ggplot2)
library(dplyr)
library(RSQLite)
#q3 data from sql
q3m <- dbGetQuery(conn, "
SELECT Year, Origin, Dest, COUNT(FlightNum) AS Total
FROM ontime
WHERE Cancelled = 0 AND Diverted = 0
GROUP BY Origin,Dest,Year
")
q3m
#ggplot
q3plot <- ggplot(q3m) +
geom_col(aes(x= Year, y = Total))+
scale_x_discrete(limits = c(2000,2001)) +
facet_wrap(~Dest) +
labs(title = paste(q3m$Origin , "to" ) , x = "Year", y = "Total Flights") +
geom_text(aes(x = Year, y = Total, label = Total), vjust = 1.5, size = 3.5, color = "white")
q3plot
SHINY
library(shiny)
server <- function(input,output, session) {
#data
data <- reactive({
req(input$sel_q3)
q3m
})
#plot
output$plot <- renderPlot({
q3plot <- ggplot(data(),aes(x= Year, y = Total)) + scale_x_discrete(limits = c(2000,2001)) +
facet_wrap(~Dest) +
geom_col()
})
#update dynamically
observe({
updateSelectInput(session, "sel_q3", choices = q3m$Origin)
})
}
ui <- fluidPage(
h1("Comparison of total flights of airport"),
selectInput(inputId = "sel_q3",
label = "Select your airport",
"Names"),
plotOutput("plot")
)
shinyApp(ui=ui, server = server)
SHINY shows graph but the graph does not change
What i did was just put q3plot into output$plot instead of retyping ggplot
server <- function(input,output, session) {
#data
data <- reactive({
req(input$sel_q3)
q3m
})
#plot
output$plot <- renderPlot({
q3plot
})
#update dynamically
observe({
updateSelectInput(session, "sel_q3", choices = q3m$Origin)
})
}
ui <- fluidPage(
h1("Comparison of total flights of airport"),
selectInput(inputId = "sel_q3",
label = "Select your airport",
"Names"),
plotOutput("plot")
)
shinyApp(ui=ui, server = server)
Thanks to #MrFlick
The solution if anyone faces the same issue is basically adding the proper filtering
#data
data <- reactive({
req(input$sel_q3)
df <- q3m %>% filter(Origin %in% inputsel_q3) # <- this is the fix
})
#plot
output$plot <- renderPlot({
ggplot(data(),aes(x,y)) + geomcol()
})

how can I compare between two ggplots in R studio in layers ( in other words having two plots over each other and compare them through my inputs )?

I have two output plots and I want to get them above each other, so I can compare between them through the selected inputs input$sel and input$sel2.
I mean with above each other is one should be in the background and the other one should be another layer on it transparent, so one can see both plots at the same time.
If data are necessary, here is data.csv file :
https://impfdashboard.de/static/data/germany_vaccinations_by_state.tsv
server <- function(input, output, session) {
#Summarize Data and then Plot
data <- reactive({
req(input$sel)
df <- germany_vaccinations_k %>% group_by(code) %>% summarise( output = get(input$sel))
print(df)
})
data2 <- reactive({
req(input$sel2)
df <- germany_vaccinations_k %>% group_by(code) %>% summarise( output = get(input$sel2))
print(df)
})
#Plot 1
output$plot <- renderPlot({
g <- ggplot( data(), aes( y = output ,x = code ,ho = factor(code) ) )
g + geom_bar( stat = "sum" )
output$plot2 <- renderPlot({
g <- ggplot( data(), aes( y = output ,x = code ,ho = factor(code) ) )
g + geom_bar( stat = "sum" )
})
ui <- basicPage(
#first-input
selectInput(inputId = "sel", label = "Möglichkeit auswählen",
list("vaccinationsTotal","peopleFirstTotal","peopleFullTotal","peopleBoosterTotal")),
#second-input
selectInput(inputId = "sel2", label = "Möglichkeit auswählen",
list("vaccinationsTotal","peopleFirstTotal","peopleFullTotal","peopleBoosterTotal")),
#the both outputs
plotOutput("plot")
plotOutput("plot2")
)
We can combine both plots and play around with alpha argument. I added two sliders that enables the user to control the level of transparency of both plots.
output$plot <- renderPlot({
ggplot() +
geom_bar(data = data(), aes(y = output, x = code), stat = "sum", alpha = .5) +
geom_bar(data = data2(), aes(y = output, x = code), stat = "sum", alpha = .5, fill = "lightblue")
})
app:
germany_vaccinations_k <- read_tsv("germany_vaccinations_by_state.tsv")
ui <- basicPage(
# first-input
selectInput(
inputId = "sel", label = "Möglichkeit auswählen",
list("vaccinationsTotal", "peopleFirstTotal", "peopleFullTotal", "peopleBoosterTotal")
),
# second-input
selectInput(
inputId = "sel2", label = "Möglichkeit auswählen",
list("vaccinationsTotal", "peopleFirstTotal", "peopleFullTotal", "peopleBoosterTotal")
),
sliderInput("alpha_sel", "Select First Alpha", min = .01, max = 1, value = 0.5),
sliderInput("alpha_sel2", "Select Second Alpha", min = .01, max = 1, value = 0.8),
# the both outputs
plotOutput("plot")
)
server <- function(input, output, session) {
# Summarize Data and then Plot
data <- reactive({
req(input$sel)
df <- germany_vaccinations_k %>%
group_by(code) %>%
summarise(output = get(input$sel))
print(df)
})
data2 <- reactive({
req(input$sel2)
df <- germany_vaccinations_k %>%
group_by(code) %>%
summarise(output = get(input$sel2))
print(df)
})
output$plot <- renderPlot({
ggplot() +
geom_bar(data = data(), aes(y = output, x = code), stat = "sum", alpha = input$alpha_sel) +
geom_bar(data = data2(), aes(y = output, x = code), stat = "sum", alpha = input$alpha_sel2, fill = "lightblue")
})
}
shinyApp(ui, server)

R Shiny ggplot reactive to dateRangeInput

I am relatively new to R, and I'm trying to build a reactive ggplot in Shiny where the X-axis (dates) is reactive to a dateRangeInput in the UI. I've been googling everywhere, but every thing I try returns an error.
In the ggplot, the aes() calls from a dataset called datecorrected_totals, where x is the dates, and y=load are the two values that I would like to be reactive to the dateRangeInput so the ggplot will adjust the scale based on the period within the daterangeinput.
library(tidyverse)
library(shiny)
library(tidyr)
library(lubridate)
library(zoo)
data <- read_csv("--")
# Define UI ----
ui <- fluidPage(
titlePanel("--"),
sidebarLayout(
sidebarPanel(
h3("Calculator"),
dateRangeInput("dates", label = "Dates",
start = ("10-18-2018"),
end = max("05-29-2019"),
min = min("10-18-2018"),
max = max("05-29-2019"),
format = "mm-dd-yyyy"),
sliderInput("slider_a", label = "--",
min = 0,
max = 7,
value = 0),
sliderInput("slider_c", label = "--",
min = 7,
max = 42,
value = 7)
),
mainPanel(plotOutput('bar_chart'))
)
)
# Define server logic ----
server <- function(input, output, session) {
RE <- reactive({
})
output$bar_chart <- renderPlot(
ggplot(data = datecorrected_totals, aes(x = x, y = load)) +
geom_bar(stat = "identity")
)
}
# Run the app ----
shinyApp(ui = ui, server = server)
You need to filter the original dataset by the input dates. In this example data would be your original dataset.
RE <- reactive({
data %>%
filter(x>=input$dates[1] & x<=input$dates[2])
})
output$bar_chart <- renderPlot(
ggplot(data = RE(), aes(x = x, y = load)) +
geom_bar(stat = "identity")
There is no need to create a separate reactive() expression (unless required otherwise). The filter can be applied directly in renderPlot(). Thus, output$bar_chart becomes
output$bar_chart <- renderPlot(
datecorrected_totals %>%
filter(between(x, input$dates[1], input$dates[2])) %>%
ggplot(aes(x = x, y = load)) +
geom_bar(stat = "identity")
)
Below is a self-contained minimal reproducible example:
library(tidyverse)
library(lubridate)
library(shiny)
datecorrected_totals <- tibble(x = seq(as.Date("2018-10-18"), as.Date("2019-05-29"), length.out = 10L),
load = day(x))
# Define UI ----
ui <- fluidPage(
titlePanel("--"),
sidebarLayout(
sidebarPanel(
h3("Calculator"),
dateRangeInput("dates", label = "Dates",
start = mdy("10-18-2018"),
end = mdy("05-29-2019"),
min = mdy("10-18-2018"),
max = mdy("05-29-2019"),
format = "mm-dd-yyyy"),
),
mainPanel(plotOutput('bar_chart'))
)
)
# Define server logic ----
server <- function(input, output, session) {
output$bar_chart <- renderPlot(
datecorrected_totals %>%
filter(between(x, input$dates[1], input$dates[2])) %>%
ggplot(aes(x = x, y = load)) +
geom_col()
)
}
# Run the app ----
shinyApp(ui = ui, server = server)
Note that the date strings have been coerced to valid Date objects by calling mdy() to avoid error messages.
In addition, geom_bar(stat = "identity") has been replaced by geom_col().

Show a modal dialog with a plot in Shiny Application

I have the following Shiny Application:
dates <- seq(as.Date("2018-01-01"), as.Date("2018-05-01"), by="days")
point_duration = rnorm(n=length(dates), mean=6, sd=1)
point_duration_bench = rnorm(n=length(dates), mean=5, sd=2)
df <- data.frame(dates, point_duration, point_duration_bench)
df$week <- strftime(df$dates, format = "%V")
df$month <- strftime(df$dates, format = "%m")
current_day = Sys.Date()
current_week = strftime(current_day, format = "%V")
current_month = strftime(current_day, format = "%m")
library(shiny)
library(ggplot2)
library(plotly)
library(shinyBS)
UI <- fluidPage(
actionButton("month","Show last week"),
plotOutput("line_graph"),
bsModal("modalExample", "Your plot", "go", size = "large",plotOutput("plot"),downloadButton('downloadPlot', 'Download'))
)
Server <- function(input, output) {
observeEvent(input$month, {
output$plot <- renderPlot({
hist(50)
})
})
output$line_graph <- renderPlot({
ggplot(df, aes(x=dates, y=point_duration)) +
geom_bar(stat = "identity") +
geom_line(aes(x=dates, y = point_duration_bench), colour = "blue") +
geom_point() +
labs(y="Amount of calls (#1000)",x="")
})
}
shinyApp(ui = UI, server = Server)
With the bsModal function I try to achieve that when you press the month button you get a popup screen showing a the plot output (in this case a simple hist(50)).
However, it does not seem to work... Any thoughts on where I go wrong?
You need to connect the modal output to the right button. You had it attached to 'go' when it needed 'month' to work. Also, I don't think you need the observer as the behavior is built in tobsModal(). See working code:
dates <- seq(as.Date("2018-01-01"), as.Date("2018-05-01"), by="days")
point_duration = rnorm(n=length(dates), mean=6, sd=1)
point_duration_bench = rnorm(n=length(dates), mean=5, sd=2)
df <- data.frame(dates, point_duration, point_duration_bench)
df$week <- strftime(df$dates, format = "%V")
df$month <- strftime(df$dates, format = "%m")
current_day = Sys.Date()
current_week = strftime(current_day, format = "%V")
current_month = strftime(current_day, format = "%m")
library(shiny)
library(ggplot2)
library(plotly)
library(shinyBS)
UI <- fluidPage(
actionButton("month","Show last week"),
plotOutput("line_graph"),
bsModal("modalExample",
"Your plot",
"month", # <----set the observer to the right button
size = "large",
plotOutput("plot"),
downloadButton('downloadPlot', 'Download'))
)
Server <- function(input, output) {
output$plot <- renderPlot({
hist(50)
})
output$line_graph <- renderPlot({
ggplot(df, aes(x=dates, y=point_duration)) +
geom_bar(stat = "identity") +
geom_line(aes(x=dates, y = point_duration_bench), colour = "blue") +
geom_point() +
labs(y="Amount of calls (#1000)",x="")
})
}
shinyApp(ui = UI, server = Server)

Resources