I'm trying to select only unique values for my range slider in my Shiny App. I am able to do this using the SliderTextInput but I'm struggling to find a way to do this for the range slider. Please see the code below. Any suggestions?
#Example dataframe:
df<- data.frame("ID" = c("001","001","001"), "date" = c("2020-07-01 01:00:00","2020-07-01 03:00:00","2020-07-01 06:00:00"))
library(shiny)
library(move)
library(amt)
library(tibble)
library(dplyr)
library(htmltools)
library(dygraphs)
library(ggplot2)
library(plotly)
library(shinythemes)
library(shinydashboard)
library(datetime)
library(shinyTime)
shinyServer(function(input, output, session) {
observeEvent(input$selectVariable, {
min<- min(as.POSIXct(df$date))
max<- max(as.POSIXct(df$date))
updateSliderTextInput(session, "month", choices = sort(unique(df$date)), selected = sort(unique(df$date)))
updateSliderInput(session, "falltime", min = min, max = max, value =sort(unique(as.POSIXct(df$date))), timezone = "MST")
})
})
shinyUI(navbarPage(
tabPanel("Analysis",
sidebarLayout(
sidebarPanel(width = 5,
selectInput("selectVariable", "Select an ID:",
choices = unique(df$ID)),
sliderTextInput("month",
"Date Range Correct:",
choices = sort(unique(df$date))), #This slider works with the expected behavior but I need it to be a range slider
sliderInput('falltime',"Slider Incorrect Date Range:", min = as.POSIXct("2020-01-01 00:00:00", tz = "MST"), max = as.POSIXct("2020-02-02 00:00:00", tz = "MST"),
value = c(as.POSIXct("2020-01-01 00:00:00", tz = "MST"),as.POSIXct("2020-02-01 00:00:00", tz = "MST"))#, step =
)), #Can't figure out how to make this slider select only unique values
mainPanel(h2("Uploaded Data")))
)
)
)
You can use sliderTextInput for that as well. It has choices argument which can take all the unique values that you want to show and selected argument which will show the first range selected by default.
library(shiny)
library(shinyWidgets)
df<- data.frame("ID" = c("001","001","001"), "date" = as.POSIXct(c("2020-07-01 01:00:00","2020-07-01 03:00:00","2020-07-01 06:00:00")))
df
server <- function(input, output, session) {
}
ui <- navbarPage(
tabPanel("Analysis",
sidebarLayout(
sidebarPanel(width = 5,
selectInput("selectVariable", "Select an ID:",
choices = unique(df$ID)),
sliderTextInput("month",
"Date Range Correct:",
choices = sort(unique(df$date))),
sliderTextInput('falltime',"Slider Incorrect Date Range:",
choices = unique(df$date), selected = range(df$date)
)),
mainPanel(h2("Uploaded Data")))
)
)
shinyApp(ui, server)
Related
I would like to click on a point in dygraph and get its corresponding date in "%Y-%m-%d %H:%M:%S" format. Here I've reproduced my problem:
library(dygraphs)
library(tidyverse)
library(data.table)
library(shiny)
dates <- seq(as.POSIXct("2021-01-01 05:00:00"), as.POSIXct("2021-01-05 05:00:00"), by = 8*3600)
set.seed(24)
df <- data.table(date = dates,
percentage = round(runif(length(dates), min = 0, max = 1), digits = 2)
)
ui <- fluidPage(
fluidRow(
column(width = 12,
dygraphOutput("dygraph")
)
),
fluidRow(
verbatimTextOutput("click")
)
)
server <- function(input, output){
output$dygraph <- renderDygraph({
dygraph(df)
})
output$click <- renderPrint({
input$dygraph_click$x
})
}
shinyApp(ui = ui, server = server)
Here is how the output looks like:
My problem is that it doesn't give me the right format. I tried to use the format function, but it did not work. I used the following line inside my renderprint:
format(as.POSIXct(input$dygraph_click$x), "%Y-%m-%d %H:%M:%S")
And here is the output:
It does not show the hour:minute:second properly.
Does anyone know how I can print out the POSIXct format of a date upon clicking on its corresponding point? I would appreciate any help.
You can use lubridate::ymd_hms to convert input$dygraph_click$x in POSIXct format and use format to display the output.
output$click <- renderPrint({
format(lubridate::ymd_hms(input$dygraph_click$x, tz = Sys.timezone()))
})
Complete code -
library(dygraphs)
library(tidyverse)
library(data.table)
library(shiny)
dates <- seq(as.POSIXct("2021-01-01 05:00:00"),
as.POSIXct("2021-01-05 05:00:00"), by = 8*3600)
set.seed(24)
df <- data.table(date = dates,
percentage = round(runif(length(dates), min = 0, max = 1), digits = 2)
)
ui <- fluidPage(
fluidRow(
column(width = 12,
dygraphOutput("dygraph")
)
),
fluidRow(
verbatimTextOutput("click")
)
)
server <- function(input, output){
output$dygraph <- renderDygraph({
dygraph(df)
})
output$click <- renderPrint({
format(lubridate::ymd_hms(input$dygraph_click$x, tz = Sys.timezone()))
})
}
shinyApp(ui = ui, server = server)
I am building an app with many charts and using spinners while waiting for them to generate.
I found if I add spinner to the charts, my date input no longer works.
I dont understand this behaviour, nor know how to fix it.
Here is my example:
library(data.table)
library(tidyverse)
library(shinydashboard)
library(highcharter)
library(lubridate)
library(shiny)
library(shinyWidgets)
library(shinycssloaders)
db <- mtcars
sidebar <- dashboardSidebar()
body <- dashboardBody(
h2("Test"),
box(title = "Date",width =12,
column(dateInput('startdate','',value = dmy("1/1/2017"), min = NULL, max = NULL,
format = "yyyy-mm-dd", startview = "month", weekstart = 0,language = "en", width = NULL),width = 3)
),
highchartOutput("hc")%>%withSpinner()
)
header <- dashboardHeader()
ui <- dashboardPage(header,sidebar,body)
server <- function(input, output, session) {
output$hc <- renderHighchart({
hc <- highchart() %>%
hc_add_series(name = "mpg", data = db$mpg) %>%
hc_add_series(name = "wt", data = db$wt)
hc
})
}
shinyApp(ui, server)
If I were to remove withSpinner(), I then can select the date.
I got a love-hate relationship with those spinners. Anyways: putting your graph in a fluidrow (and column) solved the problem for me:
library(data.table)
library(tidyverse)
library(shinydashboard)
library(highcharter)
library(lubridate)
library(shiny)
library(shinyWidgets)
library(shinycssloaders)
db <- mtcars
sidebar <- dashboardSidebar()
body <- dashboardBody(
h2("Test"),
box(title = "Date",width =12,
column(dateInput('startdate','',value = dmy("1/1/2017"), min = NULL, max = NULL,
format = "yyyy-mm-dd", startview = "month", weekstart = 0,language = "en", width = NULL),width = 3)
),
fluidRow(
column(
width = 12,
shinycssloaders::withSpinner(highchartOutput("hc"))
)
)
)
header <- dashboardHeader()
ui <- dashboardPage(header,sidebar,body)
server <- function(input, output, session) {
output$hc <- renderHighchart({
hc <- highchart() %>%
hc_add_series(name = "mpg", data = db$mpg) %>%
hc_add_series(name = "wt", data = db$wt)
hc
})
}
shinyApp(ui, server)
This is might suggest it was also weirdly applied to other aspects of your page rather than only your graph?
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)
I am trying to build a shiny app to show COVID-19 cases for the 10 worst affected countries with refreshes daily from the ECDC website. I want to be able to limit cases and deaths using slider inputs, and select date periods with date inputs, (all already added).
The code is below, but when I run the app I get a blank plot, the axis are displaying correctly but I can't get the points to appear. This should be able to run on any computer as the code just downloads the data set from the ECDC page.
Any solutions?
library(shiny)
library(readxl)
library(dplyr)
library(httr)
library(ggplot2)
library(plotly)
url <- paste("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide-",format(Sys.time(), "%Y-%m-%d"), ".xlsx", sep = "")
GET(url, authenticate(":", ":", type="ntlm"), write_disk(tf <- tempfile(fileext = ".xlsx")))
data <- read_excel(tf)
include<-c("United_Kingdom","Italy","France","China",
"United_States_of_America","Spain","Germany",
"Iran","South_Korea","Switzerland")
ui <- fluidPage(
titlePanel("COVID-19 Daily Confirmed Cases & Deaths"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("Country", "Select Country", selected = NULL, inline = FALSE,
width = NULL),
dateRangeInput("DateRep","Select Date Range", start = "2019-12-31", end = NULL),
sliderInput("Cases","Select Cases Range", min = 1, max = 20000, value = NULL),
sliderInput("Deaths", "Select Death Range", min = 1, max = 10000, value = 100),
submitButton("Refresh")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output) {
output$plot <- renderPlot({
include<-input$Country
plot_data<-filter(data, `Countries and territories` %in% include)%>%
filter(between(input$Cases))
plot_data%>% ggplot(aes(x=input$DateRep, y=input$Cases, size =input$Deaths, color = input$Country)) +
geom_point(alpha=0.5) +
theme_light()
})
}
shinyApp(ui = ui, server = server)
I think it would be better to define and filter the data you want to plot in a reactive expression outside of renderPlot. It will allow you to re-use these data more easily and it is easier (from my point of view) to use ggplot without inputs directly in it.
I include as.Date(DateRep) >= input$DateRep[1] & as.Date(DateRep) <= input$DateRep[2]) in filter to select the interval between the two chosen dates. Since the column DateRep has a POSIXct format, you need to use as.Date on it to convert it to the format dateRangeInput produces.
Here's the result:
library(shiny)
library(readxl)
library(dplyr)
library(httr)
library(ggplot2)
library(plotly)
url <- paste("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide-",format(Sys.time(), "%Y-%m-%d"), ".xlsx", sep = "")
GET(url, authenticate(":", ":", type="ntlm"), write_disk(tf <- tempfile(fileext = ".xlsx")))
data <- read_excel(tf)
include<-c("United_Kingdom","Italy","France","China",
"United_States_of_America","Spain","Germany",
"Iran","South_Korea","Switzerland")
ui <- fluidPage(
titlePanel("COVID-19 Daily Confirmed Cases & Deaths"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("Country", "Select Country", choices = include, selected = "France"),
dateRangeInput("DateRep","Select Date Range", start = "2019-12-31", end = NULL),
sliderInput("Cases","Select Cases Range", min = 1, max = 20000, value = NULL),
sliderInput("Deaths", "Select Death Range", min = 1, max = 10000, value = 100),
submitButton("Refresh")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output) {
plot_data <- reactive({
filter(data, `Countries and territories` %in% input$Country
& as.Date(DateRep) >= input$DateRep[1]
& as.Date(DateRep) <= input$DateRep[2]) %>%
filter(between(Cases, 1, input$Cases))
})
output$plot <- renderPlot({
plot_data() %>%
ggplot(aes(x = as.Date(DateRep), y= Cases, size = Deaths, color = `Countries and territories`)) +
geom_point(alpha=0.5) +
theme_light()
})
}
shinyApp(ui = ui, server = server)
I started to fix this, but ran out of time... so here's what I did, maybe you can complete it...
library(shiny)
library(readxl)
library(dplyr)
library(httr)
library(ggplot2)
library(plotly)
url <- paste("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide-",format(Sys.time(), "%Y-%m-%d"), ".xlsx", sep = "")
GET(url, authenticate(":", ":", type="ntlm"), write_disk(tf <- tempfile(fileext = ".xlsx")))
data <- read_excel(tf)
ui <- fluidPage(
titlePanel("COVID-19 Daily Confirmed Cases & Deaths"),
sidebarLayout(
sidebarPanel(
uiOutput("country_checkbox"),
dateRangeInput("DateRep","Select Date Range", start = "2019-12-31", end = NULL),
sliderInput("Cases","Select Cases Range", min = 1, max = 20000, value = NULL),
sliderInput("Deaths", "Select Death Range", min = 1, max = 10000, value = 100)
#submitButton("Refresh")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output) {
output$country_checkbox <- renderUI({
countries <- unique(data.frame(data)[, "Countries.and.territories"])
checkboxGroupInput("country", "Select Country",
choices = countries,
selected = NULL, inline = FALSE,
width = NULL)
})
output$plot <- renderPlot({
include<-input$country
plot_data<-filter(data, `Countries and territories` %in% include)%>%
filter(between(Cases, 1, input$Cases))
plot_data%>% ggplot(aes(x=DateRep, y=Cases, size =Deaths, color = `Countries and territories`)) +
geom_point(alpha=0.5) +
theme_light()
})
}
shinyApp(ui = ui, server = server)
I'm trying to use a date range function to alter the data used to display a histogram in R Shiny. I have some incomplete code as I cant figure out how to code this in the server function. see bellow for a minimal code example and where I think some code should go. :
library(shiny)
set.seed(123)
N<- 500
M<-56
EF<- matrix( rnorm(N*M,mean=23,sd=3), N, M)
WM<- matrix( rnorm(N*M,mean=20,sd=3), N, M)
DP<- matrix( rnorm(N*M,mean=25,sd=3), N, M)
Date <- seq(as.Date("2018-01-01"), as.Date("2018-02-25"), by="days")
Date <- as.POSIXct(Date, format = "%Y-%m-%d %H:%M")
ui <- fluidPage(
titlePanel(code(strong("Measures"), style = "color:black")),
sidebarLayout(
sidebarPanel(
strong("Tools:"),
selectInput("Test",
label = "Choose a measure to display",
choices = c("EF",
"WM",
"DP"
),
selected = "EF"),
dateRangeInput("DateRange", label= "Date Range:", start ="2018-01-01", end = "2018-02-25")),
mainPanel(
code(strong("Study Readout")),
plotOutput("distPlot")
))
)
server <- function(input, output) {
filterData <- reactive({
x <- switch(input$Test,
"EF" = EF,
"WM" = WM,
"DP" = DP)
return(x)
})
output$distPlot <- renderPlot({
x <-filterData()
DateRange <- #????
hist(x, #????)
})
}
# Run that shit ----
shinyApp(ui = ui, server = server)
You could just subset your vector x according to the date range, comment out the conversion to POSIXct and fill the blanks like this.
library(shiny)
set.seed(123)
N<-500
M<-56
EF<- matrix( rnorm(N*M,mean=23,sd=3), N, M)
WM<- matrix( rnorm(N*M,mean=20,sd=3), N, M)
DP<- matrix( rnorm(N*M,mean=25,sd=3), N, M)
Date <- seq(as.Date("2018-01-01"), as.Date("2018-02-25"), by="days")
#Date <- as.POSIXct(Date, format = "%Y-%m-%d")
ui <- fluidPage(
titlePanel(code(strong("Measures"), style = "color:black")),
sidebarLayout(
sidebarPanel(
strong("Tools:"),
selectInput("Test",
label = "Choose a measure to display",
choices = c("EF",
"WM",
"DP"
),
selected = "EF"),
dateRangeInput("DateRange", label= "Date Range:", start ="2018-01-01", end = "2018-02-25")),
mainPanel(
code(strong("Study Readout")),
plotOutput("distPlot")
))
)
server <- function(input, output) {
filterData <- reactive({
x <- switch(input$Test,
"EF" = EF,
"WM" = WM,
"DP" = DP)
return(x)
})
output$distPlot <- renderPlot({
x <-filterData()
hist(x[Date >= min(input$DateRange) & Date <= max(input$DateRange)])
})
}
shinyApp(ui = ui, server = server)