R Shiny code -- Reactive slider for ggplot histogram - r

I am trying to program a shiny dashboard with a histogram that allows you to subset the input data according to dates.
I have the date input bar functioning, but it only provides data for a single point in time, not a range. Can someone point out where I went wrong in the code?
I will provide my server.r and ui.r code, as well as reproducible data.
SERVER.R
library(reshape)
library(shiny)
library(ggplot2)
# GEN DATA -----------------------------------------------
dates = c("2014-01-01", "2014-02-01", "2014-03-01", "2014-04-01", "2014-01- 01", "2014-02-01", "2014-03-01", "2014-04-01", "2014-01-01", "2014-02-01")
value = c ("3.2", "4.1", "3.8", "5.6", "2.1", "2.0", "1.0" , "4.5", "1.6", "2.9")
dataset = cbind(dates, value)
dataframe = data.frame(dataset)
dataframe$dates <- as.Date(dataframe$dates, format = "20%y-%m-%d")
dataframe$value <- as.numeric(dataframe$value)
# SERVER -----------------------------------------------
shinyServer(function (input, output) {
# DATA
data.r = reactive({
a = subset(dataframe, dates %in% input$daterange)
return(a)
})
# GGPLOT
mycolorgenerator = colorRampPalette(c('sienna','light grey'))
output$myplot = renderPlot({
dd<-data.r()
# ggplot with proper reference to reactive function <<data.r()>>
s = ggplot(data=subset(dataframe, dates %in% input$daterange ), aes (x=value)) + geom_histogram(data=subset(dd, dates%in% input$daterange ) , aes(x=value))
print(s)
})
})
ui.R
# INPUT PART
library(shiny)
shinyUI(pageWithSidebar(
# Application title
headerPanel("My App"),
sidebarPanel(
dateRangeInput("daterange", "Date range:",
start = "2014-01-01",
end = "2014-03-31",
min = "2014-01-01",
max = "2014-03-31",
format = "yyyy/mm/dd",
separator = "-"),
submitButton(text="Update!")
),
# -----------------------------------------------
# OUTPUT PART
mainPanel(
tabsetPanel(
tabPanel("Tab 1", h4("Head 1"),plotOutput("myplot"))
)
)
))

You are doing string matching here not date interval checking. For what you have to work the daterange would need to contain the exact same values as your data and return more than two dates which that UI control isn't setup to do.
I think something like this might work for you.
# inside interval
start <- ymd("2014-01-01")
end <- ymd("2014-02-01")
my.interval <- interval(start, end)
ymd("2014-01-05") %within% my.interval
[1] TRUE
# outside interval
start <- ymd("2014-01-01")
end <- ymd("2014-02-01")
my.interval <- interval(start, end)
ymd("2014-03-21") %within% my.interval
[1] FALSE
You don't have to use lubridate you can manage this with the base Date packages but it would require some work.
Another work around would be to use a different control with all the date hardcoded and enable a multiselect on the input. Such as selectizeInput(...).

Modify your code like the following, your subsetting was not correct:
server <- shinyServer(function (input, output) {
# DATA
data.r = reactive({
a = subset(dataframe, dates >= input$daterange[1] &
dates <= input$daterange[2]) # add some validation code here
# to validate that input$daterange[2] >= input$daterange[1]
return(a)
})
# GGPLOT
mycolorgenerator = colorRampPalette(c('sienna','light grey'))
output$myplot = renderPlot({
dd<-data.r()
# ggplot with proper reference to reactive function <<data.r()>>
print(ggplot(dd, aes(x=value)) + geom_histogram())
})
})
# INPUT PART
library(shiny)
ui <- shinyUI(pageWithSidebar(
# Application title
headerPanel("My App"),
sidebarPanel(
dateRangeInput("daterange", "Date range:",
start = "2014-01-01",
end = "2014-03-31",
min = "2014-01-01",
max = "2014-03-31",
format = "yyyy/mm/dd",
separator = "-"),
submitButton(text="Update!")
),
# OUTPUT PART
mainPanel(
tabsetPanel(
tabPanel("Tab 1", h4("Head 1"),plotOutput("myplot"))
)
)
))
shinyApp(ui = ui, server = server)

Related

Referencing a selected input into a dataset?

I am currently having issues with my R.Shiny app which I have designed. The UI has a drop down menu which selects a variable "returnvar", one of the columns in my dataframe source_file. However, upon running the code below I receive an error message stating:
Warning: Unknown or uninitialised column: 'returnvar'.
Warning: Error in : geom_line requires the following missing aesthetics: y
Does anyone know how I can reference an input into my source file? (Something to fix the error from the line source_file_filtered$returnvar) Would greatly appreciate all the help I can get for this, thanks!
App.R
# Defining UI
ui <- fluidPage(theme = shinytheme("darkly"),
navbarPage(
"App", #Title of app
tabPanel("Weekly Cumulative Returns",
sidebarPanel(
tags$h3("Input:"),
dateRangeInput("daterange", "Date range",
start = "2016-01-01",
end = "2021-04-02",
min = "2016-01-01",
max = "2021-04-02",
format = "yyyy/mm/dd",
separator = "to"),
selectInput("returnvar", "Index",
choices= names(source_file[2:(length(source_file)-1)])),
), #sidebarpanel
mainPanel(
# Output: Correlation Plot ----
plotOutput(outputId = "plot2"),
), #mainPanel
) #tabpanel
) #navbarPage
) #fluidPage
# Defining Server
server <- function(input, output) {
#plot for Weekly Cumulative Returns tab
output$plot2 <- renderPlot({
returncolumn(returnvar = input$returnvar,
daterange = input$daterange)
})
}
# Create Shiny Object
shinyApp(ui = ui, server = server)
Global.R
#choose source file to work with
file_name = file.choose()
source_file = read_csv(file_name)
source_file$Date = as.Date(source_file$Date)
#defining returncolumn as a function to return of selected variable over the selected date range in shiny
returncolumn = function(returnvar, daterange)
{
source_file_filtered <- source_file %>%
filter(Date >= daterange[1] & Date <= daterange[2])
g = ggplot(data = source_file_filtered, mapping = aes(x=Date, y=source_file_filtered$returnvar)) + geom_line(color="blue")
print(g)
}
Without the data its hard to test, but changing source_file_filtered$returnvar to source_file_filtered[[returnvar]] should make it work.
returncolumn = function(returnvar, daterange)
{
source_file_filtered <- source_file %>%
filter(Date >= daterange[1] & Date <= daterange[2])
g = ggplot(data = source_file_filtered,
mapping = aes(x = Date,
y = source_file_filtered[[returnvar]])) +
geom_line(color="blue")
print(g)
}

POSIXct axis and sliderInput in ggplot with shiny

I'm new to Shiny. I'm trying to use sliderInput for dates with ggplot and shiny. I could use dygraphs and it worked. But I'm hoping to stick with ggplot for data visualisation. R script below may be a mess. I just can't get the sliderInput to work on shiny app using ggplot.
The data set is here.
library(shiny)
library(scales)
library(ggplot2)
library(reshape2)
# Set system language as Japanese
Sys.setlocale(category = "LC_ALL", locale = "Japanese")
# Load data ---- the dataset is available at the link above.
df <-read.csv("data.csv", encoding="UTF-8", stringsAsFactors=FALSE, check.names = F)
colnames(df)[1]<-"取引オープン日" ##If the first column had extra string.
##Formating date
df$取引クローズ日edit<-gsub("/","-",df$取引クローズ日)
df$取引クローズ日edit<-as.POSIXct(df$取引クローズ日edit, format="%m-%d-%Y %H:%M")
##Pick 5 columns
df_5col<-df[,c("ロット","総ピップス","総収益","ドローダウン(差額)","取引クローズ日edit")]
##Stack dataset
stacked<-melt(df_5col,id.vars="取引クローズ日edit",variable.name="USD/pips",value.name="USD/pips(値)")
stacked$取引クローズ日edit<-as.POSIXct(stacked$取引クローズ日edit, format="%Y-%m-%d %H:%M") ##%m-%d-%Y
# User interface ----
ui <- fluidPage(
titlePanel("Autobot1"),
sidebarLayout(
sidebarPanel(
helpText("FX autobot"),
checkboxGroupInput("checkGroup", label = "Choose a variable to display",
choices = c("総収益" = "総収益", "ドローダウン(差額)" = "ドローダウン", "総ピップス" = "総ピップス", "ロット" = "ロット"),
selected = "総収益"),
sliderInput("sliderdate",
label = "可視化する期間:",
min = as.POSIXct("2020-03-24 10:23", "%Y-%m-%d %H:%M"),
max = as.POSIXct("2020-12-30 10:23", "%Y-%m-%d %H:%M"),
value=c(as.POSIXct("2020-03-24 10:23"),
as.POSIXct("2020-12-30 10:23")),
timeFormat="%Y-%m-%d %H:%M")
),
mainPanel(plotOutput("plot1"))
)
)
# Server logic
server <- function(input, output) {
output$plot1 <- renderPlot({
##filter data
df_5col%>%
filter(取引クローズ日edit == input$sliderdate) %>%
#data manipulation
data1=reactive({
return(stacked[stacked$USD/pips%in%input$checkGroup,])
})
ggplot(data=data1) +geom_line(aes(x=取引クローズ日edit, y= 総収益, colour="総収益"))+geom_line(aes(x=取引クローズ日edit, y=総ピップス, colour="総ピップス"))+geom_line(aes(x=取引クローズ日edit, y= ロット, colour="ロット"))+scale_x_datetime(labels = date_format("%Y-%m-%d %H:%M"),date_breaks = "2 months")
})
}
# Run the app
shinyApp(ui, server)
Thanks in advance
It's solved. The script below works.
library(shiny)
library(scales)
library(ggplot2)
library(reshape2)
# Set system language as Japanese
Sys.setlocale(category = "LC_ALL", locale = "Japanese")
# Load data ----
df <-read.csv("data.csv", encoding="UTF-8", stringsAsFactors=FALSE, check.names = F)
colnames(df)[1]<-"取引オープン日" ##If the first column had extra string.
##Formating date
df$取引クローズ日edit<-gsub("/","-",df$取引クローズ日)
df$取引クローズ日edit<-as.POSIXct(df$取引クローズ日edit, format="%m-%d-%Y %H:%M")
##Pick 5 columns
df_5col<-df[,c("ロット","総ピップス","総収益","ドローダウン(差額)","取引クローズ日edit")]
##Stack dataset
stacked<-melt(df_5col,id.vars="取引クローズ日edit",variable.name="USD/pips",value.name="USD/pips(値)")
stacked$取引クローズ日edit<-as.POSIXct(stacked$取引クローズ日edit, format="%m-%d-%Y %H:%M")
# User interface ----
ui <- fluidPage(
titlePanel("title"),
sidebarLayout(
sidebarPanel(
helpText("Times-series data of FX autobot"),
checkboxGroupInput("checkGroup", label = "Choose a variable to display",
choices = c("総収益" = "総収益", "ドローダウン(差額)" = "ドローダウン(差額)", "総ピップス" = "総ピップス", "ロット" = "ロット"),
selected = "総収益"),
sliderInput("sliderdate",
label = "可視化する期間:",
min = as.POSIXct("2020-03-24 10:23"),
max = as.POSIXct(Sys.Date()),
value=c(as.POSIXct("2020-03-24 10:23"),
as.POSIXct("2020-12-30 10:23")),
timeFormat="%m-%d-%Y %H:%M")
),
mainPanel(plotOutput("plot1"))
)
)
# Server logic
server <- function(input, output) {
output$plot1 <- renderPlot({
##create the data
date1<-as.POSIXct(input$sliderdate, timeFormat="%m-%d-%Y %H:%M")
sub_data <- subset(stacked, 取引クローズ日edit >= date1[1] & 取引クローズ日edit <= date1[2])
sub_data2<-sub_data[sub_data[,2]%in%input$checkGroup,]
ggplot(data=sub_data2) +geom_line(aes(x=取引クローズ日edit, y= sub_data2[,3], color=sub_data2[,2]))+ylab("USD/pips")+xlab("取引クローズ日")+scale_x_datetime(labels = date_format("%m-%d-%Y"),date_breaks = "1 month")
})
}
# Run the app
shinyApp(ui, server)

Using validate in Shiny to hide plot without relevant data when using reactive function (R)

I have created an app using Shiny that displays data dependent on two different inputs. I'm filtering the data in a reactive function and then passing this through to the plots.
I can't work out how to simply hide the plots (and ideally show a helpful explanation) when there is no relevant data based on the inputs. I could do this if my data was in a dataframe, but as I have filtered it using a reactive function, this doesn't work.
I currently have the validate function nested in the renderPlot function, referencing the dataframe that is filtered by the reactive function...
Does anybody have any thoughts?
Reproducible code (if you select "Bristol" with the default date range, that demonstrates the issue):
library("tidyverse")
location <- as.character(c("London", "London", "Birmingham", "Bristol", "Birmingham", "Birmingham", "London", "Birmingham"))
dog_birthday <- as.POSIXct(c("01-01-2016", "02-02-2016", "03-03-2016", "04-04-2017", "05-05-2017", "06-06-2017", "08-08-2018", "07-07-2018"), format = "%d-%m-%Y")
dog_type <- as.character(c("Poodle", "Pug", "Labrador", "Poodle", "Poodle", "Labrador", "Pug", "Pug"))
dog_data <- data.frame(location, dog_birthday, dog_type)
ui<-
fluidPage(
sidebarLayout(
sidebarPanel(
dateRangeInput(
"dates", label = h3("Birthdate range"), start = ("01-06-2018"),
format = "dd-mm-yyyy", startview = "year"
),
selectInput(
"location", label = h3("Location"), choices = unique(dog_data$location),
multiple = T, selectize = T
)
),
mainPanel(
plotOutput(outputId = "dog_type")
)
)
)
server <- function(input, output) {
city_selection <- reactive({
req(input$location)
choose_city <- subset(dog_data, dog_data$location %in% input$location)
choose_city <- droplevels(choose_city)
return(choose_city)
})
output$dog_type <- renderPlot({
validate(
need(nrow(dog_data) > 0, "No data for this selection.")
)
dog_type_plot <- city_selection() %>%
filter(dog_birthday >= input$dates[1] & dog_birthday <= input$dates[2]) %>%
count(dog_type) %>%
arrange(-n) %>%
mutate(dog_type = factor(dog_type, dog_type)) %>%
ggplot(aes(dog_type, n)) +
geom_bar(stat = "identity")
dog_type_plot
})
}
shinyApp(ui, server)
You need to move the dates filter to the city_selection reactive and update the need condition in validate -
server <- function(input, output) {
city_selection <- reactive({
req(input$location)
choose_city <- subset(dog_data, dog_data$location %in% input$location) %>%
filter(dog_birthday >= input$dates[1] & dog_birthday <= input$dates[2])
choose_city <- droplevels(choose_city)
return(choose_city)
})
output$dog_type <- renderPlot({
validate(
need(nrow(city_selection()) > 0, "No data for this selection.")
)
dog_type_plot <- city_selection() %>%
count(dog_type) %>%
arrange(-n) %>%
mutate(dog_type = factor(dog_type, dog_type)) %>%
ggplot(aes(dog_type, n)) +
geom_bar(stat = "identity")
dog_type_plot
})
}
I also got an error trying to run the code:
Warning: Error in count: Argument 'x' must be a vector: list
A few other things that I noticed:
For me, choose_city <- droplevels(choose_city) doesn't do anything, I think you need choose_city$location <- droplevels(choose_city$location) if you're trying to remove the un-selected factor levels from location
I think #Shree's suggestion will help, but this method still only checks for the location, not the dates. (The reason your version doesn't do anything is because dog_data is your reference data.frame, and it doesn't get changed by your subsetting) #Shree's updated answer moved the date subset and now is probably better than this one :)
I changed your code a decent amount to get it to work for me (just because I don't use pipes and am most familiar with data.table). Obviously you can just remove the data.table dependency and filter with pipes!
The main thing is just that you want to check what dog_type_plot looks like right before making the plot. I added a reactiveVal to hold a message that's output in the sidebar:
library("tidyverse")
library("data.table")
location <- as.character(c("London", "London", "Birmingham", "Bristol", "Birmingham", "Birmingham", "London", "Birmingham"))
dog_birthday <- as.POSIXct(c("01-01-2016", "02-02-2016", "03-03-2016", "04-04-2017", "05-05-2017", "06-06-2017", "08-08-2018", "07-07-2018"), format = "%d-%m-%Y")
dog_type <- as.character(c("Poodle", "Pug", "Labrador", "Poodle", "Poodle", "Labrador", "Pug", "Pug"))
dog_data <- data.frame(location, dog_birthday, dog_type)
ui<-
fluidPage(
sidebarLayout(
sidebarPanel(
dateRangeInput(
"dates", label = h3("Birthdate range"), start = ("01-06-2018"),
format = "dd-mm-yyyy", startview = "year"
),
selectInput(
"location", label = h3("Location"), choices = unique(dog_data$location),
multiple = T, selectize = T
),
textOutput(outputId = "noDataMsg")
),
mainPanel(
plotOutput(outputId = "dog_type")
)
)
)
server <- function(input, output) {
## Subset base data.frame by user-selected location(s)
city_selection <- reactive({
req(input$location)
choose_city <- subset(dog_data, dog_data$location %in% input$location)
choose_city$location <- droplevels(choose_city$location)
return(choose_city)
})
## Value to hold message
message_v <- reactiveVal(); message_v("blank")
## Make Histogram
output$dog_type <- renderPlot({
print("city_selection():")
print(city_selection())
cat("\n")
## Change to data.table
data_dt <- as.data.table(city_selection())
print("original data_dt:")
print(data_dt)
cat("\n")
## Subset by birthday
dog_type_plot <- data_dt[dog_birthday >= input$dates[1] &
dog_birthday <= input$dates[2],]
print("subset by birthday")
print(dog_type_plot)
cat("\n")
## Get counts and sort
dog_type_plot[, N := .N, by = dog_type]
dog_type_plot <- dog_type_plot[order(-N)]
print("add count:")
print(dog_type_plot)
cat("\n")
## Change dog type to factor
dog_type_plot$dog_type <- factor(dog_type_plot$dog_type, levels = unique(dog_type_plot$dog_type))
print("refactor of dog_type:")
print(dog_type_plot$dog_type)
cat("\n")
## Check for data to plot
if (nrow(dog_type_plot) == 0) {
message_v("No dogs to plot using these parameters")
return(NULL)
} else {
## Make plot
plot_gg <- ggplot(data = dog_type_plot, aes(x = dog_type, y = N)) +
geom_bar(stat = "identity")
## Return
return(plot_gg)
} # fi
}) # renderPlot
## Message to user
output$noDataMsg <- renderText({ if (message_v() == "blank") { return(NULL) } else { message_v() } })
}
shinyApp(ui, server)

ggplot aes_string not taking the x and y axis in r shiny app [duplicate]

This question already has answers here:
How to use a variable to specify column name in ggplot
(6 answers)
Closed 4 years ago.
I am trying to built a r shiny app with filtering based on date. but ggplot is not picking the x and y values and also there is number shown in place of date when i output the filtered data as a table.
data2$Deployment.Month<- as.Date(data2$Deployment.Month,format = "%d-%m-%Y")
min_date <- min(data2$Deployment.Month)
max_date <- max(data2$Deployment.Month)
data3 <- as.data.frame(data2)
data4<- na.omit(data3)
ui <- fluidPage(
sidebarLayout(
# Input(s)
sidebarPanel(
# Select variable for x-axis
selectInput(inputId = "x",
label = "Variable 1",
choices = c(choices),
selected = "Project.Id"),
# Select variable for y-axis
selectInput(inputId = "y",
label = "Variable 2",
choices = c(choices),
,
dateRangeInput(inputId = "date",
label = "Select dates:",
start = "2013-01-01",
end = "2017-12-31",
startview = "year",
min = as.Date(min_date), max = as.Date(max_date))),
mainPanel(plotOutput(outputId = "scatterplot"),tableOutput("table"))))
server<- function(input, output){
output$scatterplot <- renderPlot({req(input$date)
projects_selected_date <- data4 %>%filter(Deployment.Month >= input$date[1] & Deployment.Month <=input$date[2])
ggplot(projects_selected_date,aes_string(x=projects_selected_date$x,y=projects_selected_date$y),colour='red')+ geom_point()})
output$table <- renderTable({
projects_selected_date <- data4 %>% filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2])
projects_selected_date})}
# Create a Shiny app object
shinyApp(ui = ui, server = server)
it is showing error- error- geom_point requires the following missing aesthetics: x, y.
I need more elements to perform perfect code but try a code like this :
data4<- na.omit(data3)
ui <- fluidPage(
sidebarLayout(
# Input(s)
sidebarPanel(
# Select variable for x-axis
selectInput(inputId = "x",
label = "Variable 1",
choices = c("Col1", "Col2", "Col3"), # You have to define colnames
selected = "Col1"),
# Select variable for y-axis
selectInput(inputId = "y",
label = "Variable 2",
choices = c("Col4", "Col5", "Col6"), # Same things
selected = "Col4"),
mainPanel(plotOutput(outputId = "scatterplot"),
tableOutput("table")
)
)
)
server<- function(input, output){
output$scatterplot <- renderPlot({
projects_selected_date <- data4 %>%filter(Deployment.Month >= input$date[1] & Deployment.Month <=input$date[2])
ggplot(projects_selected_date,aes_string(x = input$x ,y = input$y,colour='red')) + geom_point()
})
### I don't know if this piece of code works !
output$table <- renderTable({
projects_selected_date <- data4 %>% filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2])
table(projects_selected_date)
)}
# Create a Shiny app object
shinyApp(ui = ui, server = server)

How can I use daterangenput for time series plot?

I have data to be plotted as series which is uploded by user. However, the data is for one year and I would like to display 2 months for instance, january and february when the user needs to analyze the pattern of these months. That's why i thought that dateRangeInput can be useful but i dont know how can i bind with plot?
for data: http://www.filedropper.com/quo
EDITED: I used the reactive argument in order get the inputs. However, it shows another error: Error in charToDate(x) :
character string is not in a standard unambiguous format.
library(shiny)
shinyUI(fluidPage(
titlePanel("Time Series Study"),
sidebarLayout(
sidebarPanel(
fileInput('file2', 'Choose Quotation File:', accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv'), multiple = FALSE),
dateRangeInput("range",
"Date Range:",
start = "start",
end = "end",
min = "2012.01.01",
max = "2012.01.31")
),
mainPanel(
plotOutput("distPlot") ) ) ))
#server.r
library(shiny)
library(ggplot2)
shinyServer(function(input, output) {
dataInput <- reactive({
`uploadedsamplefile` <- read.csv(input$file2$datapath, sep=";",check.names = FALSE)
uploadedsamplefile1 <- uploadedsamplefile
xx<-cbind(`uploadedsamplefile1`[1:4])
xx$`Datee` <- as.Date( xx$`Datee`, '%d.%m.%Y')
xx$`Datee` <- subset( xx$`Datee`, as.Date("input$start") <= xx$`Datee` && xx$`Datee` <= as.Date("input$end"))
})
output$distPlot <- renderPlot({
y <- ggplot(xx, aes(x=`Datee`)) + geom_line(aes(y=(`A`), colour = "A")) + geom_line(size=1,aes(y=(`B`), colour = "B")) +
geom_line(size=1,aes(y=(`C`), colour = "C"))
y }) })
To access the start and end dates in your example use input$range[1] for the start date and input$range[2] to access the end date.

Resources