I am developing a Shiny app. It works fine, but when I am refreshing the browser it is in, the app seemingly returns to its initial stage. How can I prevent it so that whenever I refresh I also remain in my present page?
To replicate the problem I am attaching the following example of a shiny app. How can I refresh it while preserving the last value I set it on?
library(shiny)
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
server <- function(input, output) {
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
shinyApp(ui, server)
Related
When I run a shiny application on RStudio, my app runs and the URL looks like this:
Listening on http://127.0.0.1:4991
But each time I run again the app, the port changes, I wonder if there is a way to obtain the url as a variable or something like that. I mean, each time that I run the app, I want to obtain the URL and save it in a variable.
Thank you
You can get the url with session$clientData:
library(shiny)
ui <- basicPage()
server <- function(input, output, session){
observe({
print(reactiveValuesToList(session$clientData))
})
}
shinyApp(ui, server)
You can specify the port using options:
#example: https://shiny.rstudio.com/articles/basics.html
options(shiny.host = '0.0.0.0')
options(shiny.port = 8888)
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
# Define server logic required to draw a histogram ----
server <- function(input, output) {
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
shinyApp(ui, server)
I have created the following shiny App. The App consists of the following parts
import necessary libraies
library(shiny)
library(shinyjs)
Next we create the US. Note that we are adding a toggle sidebar option using the material switch function as follows
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
useShinyjs(), navbarPage(materialSwitch(inputId = "toggleSidebar",label = "",
value = FALSE, status = "success")),
# Sidebar layout with input and output definitions ----
sidebarLayout(div( id ="Sidebar",
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30))),
# Main panel for displaying outputs ----
mainPanel( # Output: Histogram ----
plotOutput(outputId = "distPlot")
)))
Next we create a server as follows
# Define server logic required to draw a histogram ----
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")})
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar")
})}
We now run the App.
shinyApp(ui, server)
When the App runs, the sidebar containing the slider with the number of bins is collapsed as the sidebar is collapsed by default. The same can be accessed by pressing the toggle switch.
Is it possible to have the sidebar open by default and then collapse the same when the toggle switch is clicked
Thank you
You can use toggles condition argument to determine if the sidebar should be shown or hidden:
library(shiny)
library(shinyjs)
library(shinyWidgets)
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
useShinyjs(), navbarPage(materialSwitch(inputId = "toggleSidebar",label = "",
value = TRUE, status = "success")),
# Sidebar layout with input and output definitions ----
sidebarLayout(div( id ="Sidebar",
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30))),
# Main panel for displaying outputs ----
mainPanel( # Output: Histogram ----
plotOutput(outputId = "distPlot")
)))
# Define server logic required to draw a histogram ----
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")})
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar", condition = input$toggleSidebar)
})
}
shinyApp(ui, server)
I am trying to store and load the settings selected by a user in shiny but have not been able to get it to work. The dput and dget() functions seem to be working but the UI does not get updated. What am I missing?
library(shiny)
outputDir <- "responses"
saveData <- function(inData) {
# Create a unique file name
fileName <- sprintf("%s_%s.txt", as.integer(Sys.time()), digest::digest(inData))
# Write the file to the local system
dput(inData, file = paste0(outputDir, '/', fileName))
}
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30),
selectInput("columns", "Select columns to exclude From gather", multiple = T,
choices = c('choice1', 'choice2','choice3')),
actionButton('submit', "Save inputs"),
actionButton('load', "Load inputs")
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
# Define server logic required to draw a histogram ----
server <- function(input, output, session) {
AllInputs <- reactive({
reactiveValuesToList(input)
})
observeEvent(input$submit, {
saveData(AllInputs())
})
observeEvent(input$load,{
files <- list.files(outputDir, full.names = TRUE)
inData <- dget(file = files)
for (i in 1:length(inData)) {
session$sendInputMessage(names(inData)[i], list(inData[[names(inData)[i]]]))
}
})
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
shinyApp(ui, server)
I have a shiny app with a longer computation depending on the input. I am wondering if it is possible to display a text in the main panel at the same time when the computation is done (and not before).
Let's make an easy example. I simulated the longer computation with Sys.sleep():
# Define UI for application that draws a histogram
ui <- shinyUI(fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
h3('This is an example'),
plotOutput("distPlot")
)
)
))
# Define server logic required to draw a histogram
server <- shinyServer(function(input, output) {
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
Sys.sleep(5)
})
})
# Run the application
shinyApp(ui = ui, server = server)
The goal would be, to show the text 'This is an example' at the same time the computation is done and not before.
I think I have to make the text somehow reactive, but so far I haven't found a solution for this. Maybe a conditionalPanel could do it, but how can I bring the computation time in the condition? Any ideas?
Would this be what you search for? Your text variable as a reactive after observing the event of distPlot
library(shiny)
# Define UI for application that draws a histogram
ui <- shinyUI(fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
textOutput('text1'),
plotOutput("distPlot")
)
)
))
# Define server logic required to draw a histogram
server <- shinyServer(function(input, output) {
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
Sys.sleep(2)
})
observeEvent(plotOutput("distPlot"), {
output$text1 <- renderText({ paste("Number of bins:", input$bins)})
})
})
# Run the application
shinyApp(ui = ui, server = server)
I am learning the Shiny interface for R and working through the first example.
The histogram changes based on the slider input. How do I have it update continuously, while the slider is moving? Right now, it only updates when the slider stops moving.
ui.R
library(shiny)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar with a slider input for the number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
server.R
library(shiny)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
# Expression that generates a histogram. The expression is
# wrapped in a call to renderPlot to indicate that:
#
# 1) It is "reactive" and therefore should re-execute automatically
# when inputs change
# 2) Its output type is a plot
output$distPlot <- renderPlot({
x <- faithful[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
})
What I have tried:
#server.R
library(shiny)
shinyServer(function(input,output) {
x<-faithful[,2]
bins <- reactive({
seq(min(x),max(x),length.out=input$bins+1)
})
output$distPlot <- renderPlot({
hist(x,breaks=bins(),col='darkgray',border='white')})
})
Is there a way to make it react faster/real-time?
Thanks to Dean's response I investigated the shinyCustom package in github.
Here is my solution:
#Shiny UI
library(shiny)
library(shinyCustom)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar with a slider input for the number of bins
sidebarLayout(
sidebarPanel(
useShinyCustom(slider_delay = "0"), #make a call to shinyCustom, where there is no delay
customSliderInput("bins", #Use customSliderInput instead of sliderInput
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
App now updates as you move the slider