R Shiny Randomly Generated Radio Button Choices - r

I'm creating a survey in Shiny where I want the choices as represented by radio buttons to be randomly drawn. See sample code below:
library(shiny)
choices<-c("a","b","c","d","e")
x1<-sample(choices,2)
x2<-sample(choices,2)
ui<-fluidPage(
radioButtons("q1","Which do you prefer?", choices=c(x1,"No Preference"),selected=""),
radioButtons("q2","Which do you prefer?", choices=c(x2,"No Preference"),selected="")),
server <- function(input, output) {
# Not important
})
shinyApp(ui = ui, server = server)
When I run the app locally a different set of choices will be selected each time I run the app (as intended). But once I publish to shinyapps.io the choices are the same each time (as in x1 is the same each time I run the app). How can I make so that each time the app opens a new sample is taken from the choice set?

As you may know, Shiny server implements caching to improve system utilization. The problem you are having is the x1 variable is being sampled and cached between users.
The way around this problem is to sample choices into a reactiveValue and then dynamically update the radio buttons when the page loads.
Alternatively, you might try using this approach:
ui <- function(req) {
fluidPage(
x1<-sample(choices,2)
x2<-sample(choices,2)
radioButtons("q1","Which do you prefer?", choices=c(x1,"No Preference"),selected=""),
radioButtons("q2","Which do you prefer?", choices=c(x2,"No Preference"),selected=""))
...
)
}

Related

Deploy shiny app that can call runApp() inside application itself (specifically for tabulizer package)

I'm trying to deploy a Shiny app that allows the user to upload a pdf document and extract a table from a selected page. For this I'm using the package tabulizer. A basic reproducible example:
library(shiny)
library(tabulizer)
ui <- fluidPage(
fileInput("report", NULL,buttonLabel = "Upload report"),
numericInput("page","Specify page number",value = 1),
actionButton("extract","Extract"),
verbatimTextOutput("data")
)
server <- function(input, output, session) {
generate_data <- reactive({
req(input$report)
# This locate_area function calls runApp() from the tabulizer package
area <- locate_areas(file = input$report$datapath,
pages = input$page,
widget = "reduced")
table <- extract_tables(file = input$report$datapath,
pages = input$page,
area = area)
return(table)
})%>% bindCache(input$page) %>% bindEvent(input$extract)
output$data <- renderPrint({
# Just for the sake of this example to show it works
generate_data()
})
}
shinyApp(ui = ui, server = server)
If I run this locally, the locate_area() will make the pdf page pop-up on my viewer in RStudio and all is well. However, if I publish the app it doesn't run after clicking the action button. I know the problem comes from the locate_area() as it essentially calls another runApp within the shiny app. I have tried using different widgets for locate_area() to no avail. Does anybody know a way to circumvent this issue?
Judging by the relevant issues - issue 15 and issue 53 - it appears that your best way to go is really to copy the functionality from the original tabulizer function into your own app, as currently the package does not provide an easy integration with other Shiny apps.

Is it possible to display an info text when hovering over a R shiny selectInput?

I am currently building a shiny app to build biological networks. To build them, you can choose between many different parameters, which i included in different selectInputs or numericInputs.
Is it possible to have some kind of info text, when hovering the mouse over those input fields? I dont want to add 3-4 sentences of text to the title of each select/numericInput.
Thanks :)
If you don't mind an extra package dependancy then you can use bsTooltip from the shinyBS package. Note that the hover tooltip sometimes doesn't show up unless you click on the input in the RStudio viewer pane, but if you run your app in your browser, the hover trigger should work:
library(shiny)
library(shinyBS)
ui <- fluidPage(
selectInput("input1", "Select input", c("choice1", "choice2")),
bsTooltip(id = "input1",
title = "Here is some text with your instructions")
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)

R: Introducing Automation in Shiny App

I want to know the way to build a Shiny App which automatically runs functions in a scheduled time. I read this but it doesn't seem relevant to my case.
I created a function to update a google sheet, using the package googlesheet. Now the app ui looks like this.
Clicking "Manually update" button enables the app to run the functions and update the googlesheet.
But I want the app to run the same function everyday at 1pm, even without clicking "Manually update" button, while "Activate auto update" button is on.
So to summarise, I want to know
the way to automatically execute the functions at a scheduled time in shiny app.
the way to save the user input of "Activate auto update". That is to say, once you turn on this button, even if you close this app and open it again, it stays to be "on". Once you turn off this button, it stays to be "off" until the user turn it on again, even if the user shuts off the app.
I'd appreciate for any kinds of help!
ui.R
navbarPage("Automated Report Generator", id = "nav",
tabPanel("ITM",
sidebarLayout(
sidebarPanel(materialSwitch(inputId = "activateAutoITM",
label = "Activate auto update",
status = "primary", right = FALSE),
actionButton("ITM_update", "Manually update"),
width = 2),
mainPanel(div(a("Visit ITM Google Sheet",
href = "https://docs.google.com/spreadsheets/d/#########",
target="_blank")),
div(htmlOutput("gsheet_text_ITM"))
)
) # sidebarLayout
)) # navbarPage
server.R
shinyServer(function(input, output, session) {
observeEvent(input$ITM_update, {
####### Here are the functions to update google sheet########
####### But I'll just omit because of the security#########
output$gsheet_text_ITM <- renderUI({
str1 <- paste("Calculation finised.")
HTML(paste(str1))
})
}) # shinyServer

Shiny app that fetches data via URL works locally but not on shinyapps.io

I wrote a simple shiny app to illustrate a problem I am having fetching data from a website. Here is the UI code:
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("Test App"),
# Sidebar with slider inputs
sidebarLayout(
sidebarPanel(
actionButton("button", "Fetch Data")
),
mainPanel(
tabsetPanel(
tabPanel("Data", textOutput("crimelist"))
)
)
)
)
)
And here is the Server code:
library(shiny)
# Define server logic
shinyServer(function(input, output, session) {
# Get a list of the different types of crime
observeEvent(input$button, {
url <- "https://phl.carto.com/api/v2/sql?format=csv&q=SELECT
distinct rtrim(text_general_code) as text_general_code
FROM incidents_part1_part2
order by text_general_code"
crimelist <- read.csv(url(url), stringsAsFactors = FALSE)$text_general_code
output$crimelist <- renderText({crimelist})
})
})
The data being fetched is described at https://cityofphiladelphia.github.io/carto-api-explorer/#incidents_part1_part2.
When I run this shiny app in my local environment, it works perfectly. When publish it to shinyapps.io and run it, the application fails when I click the button to fetch the data. In the shiny log, it reports the following:
2017-10-11T14:46:31.242058+00:00 shinyapps[224106]: Warning in
open.connection(file, "rt") :
2017-10-11T14:46:31.242061+00:00 shinyapps[224106]: URL 'https://phl.carto.com/api/v2/sql?format=csv&q=SELECT distinct
rtrim(text_general_code) as text_general_code
2017-10-11T14:46:31.242062+00:00 shinyapps[224106]: FROM incidents_part1_part2
2017-10-11T14:46:31.242063+00:00 shinyapps[224106]: order by text_general_code': status was 'URL using bad/illegal format or missing URL'
2017-10-11T14:46:31.243062+00:00 shinyapps[224106]: Warning: Error in open.connection: cannot open connection
I am really stumped - is this a shiny server issue of some kind? If anyone out there has a clue, I am all ears!
I posted this question on multiple boards, and Joshua Spiewak on the Shinyapps.io Users Google group solved my problem:
You need to encode the URL in order for it to be valid, e.g. https://phl.carto.com/api/v2/sql?format=csv&q=SELECT%20distinct%20rtrim(text_general_code)%20as%20text_general_code%20FROM%20incidents_part1_part2%20order%20by%20text_general_code
shinyapps.io runs on Linux, so it is likely that curl is being used to fetch this URL. My guess is that you are using Windows locally, which uses a less strict mechanism that is tolerant of the spaces and newlines you have in the URL.
After making his suggested change, it works as expected now. Thanks, Joshua!

Allow user to load their data via CSV or use a sample dataset

I'm building a Shiny app that consists of
A fileInput for the user to upload a CSV of transactions
An actionButton that lets the user test the app with a pre-built dataset (i.e. without them having to load their own data).
A verbatimTextOutput that prints a preview of the dataset they're using and
Various plot and charts built using their selected dataset
If the user uploads a file, that dataset should become the "master" transactions dataset to feed the rest of the app. If they then click the "load sample data" button, that datset should turn into the "master" transactions dataset. (Extrapolate this idea to multiple alternations between them uploading data and clicking the button)
I can get this to work as follows:
# app.R
library(data.table)
library(shiny)
# UI
ui <- shinyUI(fluidPage(
fileInput(inputId='fi_file', label='Choose CSV File', accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv')),
actionButton(inputId="ab_loadSampleTransactions", label="Load Sample Transactions"),
verbatimTextOutput("vto_transactions")
))
# Server
server <- shinyServer(function(input, output) {
# When the user uploads a file, print it
observeEvent(input$fi_file, {
transactions <- read.csv(input$fi_file$datapath)
output$vto_transactions <- renderPrint(transactions)
})
# When the user clicks the button for sample transactions, print them
observeEvent(input$ab_loadSampleTransactions, {
transactions <- data.table(ID=c(1,2,3), Amount=c(100, 150, 125))
output$vto_transactions <- renderPrint(transactions)
})
# More logic involving the transactions dataset
# ...
})
# Run the application
shinyApp(ui = ui, server = server)
However, this is inefficient because it requires me to load the transactions dataset twice in order to display it and do future logic with it. I think I need to do something reactive here, but I can't figure out how since I have two separate methods for loading the data. Help?
Don't use global variables like the suggestion in the comment says.
Use reactiveValues. It sounds like you don't need this variable to be "global" in the sense that it needs to be shared with the UI and other files -- it just needs to be global within the server, correct? In that case, you can use reactiveValues and those variables can be accessed and set anywhere in your server

Resources