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)
Related
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)
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'm trying to display a heatmap I've made in plotly in my shiny app. I think the issue may be that I've saved it as an object.. but I don't know how else to display 2 different plots, one made in ggplot and the other in plotly.
library(shiny)
library(dplyr)
library(tidyverse)
library(magrittr)
library(DT)
library(ggplot2)
library(purrr)
library(shinythemes)
library(plotly)
#load indel histogram
Indel_histogram <- read.table(file = 'histogram.tsv',
sep = '\t', header = TRUE)
#load peddy relatedness data
Relatedness <- read.csv(file='peddy/mystudy.ped_check.csv')
###########################
# make relatedness matrix #
###########################
related_matrix <- Relatedness %>% select(sample_a, sample_b, rel)
#make comparison matrix
un2 <- sort(unique(unlist(related_matrix[1:2])))
out2_new <- related_matrix %>%
complete(sample_a = un2, sample_b = un2) %>%
pivot_wider(names_from = sample_b, values_from = rel)
tmp <- map2_dfc(data.table::transpose(out2_new, make.names = 'sample_a'),
out2_new[-1], coalesce) %>%
bind_cols(out2_new %>%
select(sample_a), .)
tmp2 <- column_to_rownames(tmp, var = "sample_a")
#heatmap in plotly format
heatmap %<>% as.matrix(tmp2)
#plot heatmap using plotly
plotly_heatmap <- plot_ly(z = heatmap, type = "heatmap")
#generate indel histogram
Indel_Histogram <- ggplot(Indel_histogram, aes(Length, Freq)) + geom_col()
##################
# Make Shiny App #
##################
ui <- fluidPage(theme = shinytheme("united"),
titlePanel("QC output"),
navbarPage("Menu",
tabPanel("Plots",
sidebarLayout(
sidebarPanel(
selectInput("more_plots", "Select Plot",
choices = c("Indel_Histogram","plotly_heatmap")), width=4),
mainPanel(plotOutput("more_plots"), height="100%", width=8))
)))
server <- function(input, output) {
output$more_plots <- renderPlot({
get(input$more_plots)
}, height=600)
}
shinyApp(ui = ui, server = server)
My code shows the Indel_histogram no problem, but is does not show the plotly_heatmap. If I run plotly_heatmap in my Rconsole, it displays for me... so I need help to get both the histogram and the heatmap to view in the same panel, when selected from the same input$moreplots.
The histogram works fine, so won't bother with that data. Here's a shortened version of heatmap:
structure(c(NA, -0.03991, -0.0249, -0.01788, -0.02618, -0.03991,
NA, -0.03303, 0.01615, 0.01119, -0.0249, -0.03303, NA, 0.009972,
0.01122, -0.01788, 0.01615, 0.009972, NA, 0.01927, -0.02618,
0.01119, 0.01122, 0.01927, NA), .Dim = c(5L, 5L), .Dimnames = list(
c("AD001", "AD002", "AD003", "AD004", "AD005"), c("AD001",
"AD002", "AD003", "AD004", "AD005")))
I then tried to render the plotly heatmap separately just to see if I could get it working... but again, doesn't display (not sure why)?
ui <- fluidPage(theme = shinytheme("united"),
titlePanel("QC output"),
navbarPage("Menu",
tabPanel("Plots",
sidebarLayout(
sidebarPanel(
selectInput("Plotly", "Select Plot",
choices = "heatmap"), width=4),
mainPanel(plotlyOutput("Plotly"), height="100%", width=8)),
)))
server <- function(input, output) {
output$Plotly <- renderPlotly(
plot_ly(z = ~get(input$Plotly), type = "heatmap")
)
}
shinyApp(ui = ui, server = server)
Something is clearly going wrong!
Assuming you have already created histogram and heatmap either outside ui or insider server function, you can try this
ui <- fluidPage(theme = shinytheme("united"),
titlePanel("QC output"),
navbarPage("Menu",
tabPanel("Plots",
sidebarLayout(
sidebarPanel(
selectInput("more_plots", "Select Plot",
choices = c("Indel_Histogram","plotly_heatmap")), width=4),
mainPanel(uiOutput("myplot"), height="100%", width=8)
)
)))
server <- function(input, output) {
output$hist <- renderPlot({
Indel_Histogram ## assuming you already did this histogram
})
output$heat <- renderPlotly({
plotly_heatmap ## assuming you already have this heatmap
})
output$myplot <- renderUI({
if (input$more_plots=="Indel_Histogram"){
plot <- plotOutput("hist", height=600)
}else plot <- plotlyOutput("heat")
})
}
shinyApp(ui = ui, server = server)
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)
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.