Deploying shiny apps with local dataset - r

I tried to deploy my shiny apps to xxx.shinyapps.io , but the problem is I use own dataset.
I set my dataset to my directory. but when I try to deploy it I got error.
Listening on http://127.0.0.1:45220Loading required package: DBIError in setwd("C:/Users/xxx/Dropbox/shiny/archive/db") : cannot change working directory
Thank you,

Put your dataset in a subdirectory of your shiny app directory (and change you code accordingly). Be sure to make the path to the data a relative path (not an absolute path - this generates a warning). This has worked well for me.

In server.R , have this code at the top
source("datarep.R)
Make a new .R file "datarep.R " in the same directory.
That file has just one code
data <- read.csv("data.csv")

There are two ways
Open a ".R"(navin.R e.g.) file in the app directory( where ui.r and server.R is placed) where you make the R object which contains the data
(For example: dataS <- read.csv("XX.csv"); dataT <- read.csv("YY.csv"))
and then in server.R , write the code initially: source(navin.R)
And use dataS, dataT objects as usual.
Place XX.csv and YY..csv in the same directory ( or any directory but then give the "relative path" )
and do everything as usual
For example : I used local data to make shiny Apps
https://manaswink.shinyapps.io/TelecomTower/

Adding to the comments provided by Paul
Insert the relative path to both ui.R and server.R
No need to pre-load the data file, it loads successfully along with runApp()
Finally, you can directly publish it to the shinyapps.io
Sample code:
For -> ui.R - where 'county.csv is local dataset'
county1<-read.csv("Data/county.csv")
library(shiny)
shinyUI(pageWithSidebar(..
..........
.......
Similarly,
For -> server.R
county1<-read.csv("Data/county.csv")
shinyServer(function(input, output, session) {....
......
......

Related

R Shiny Dashboard - Loading Scripts using source('file.R')

Introduction
I have created an R shiny dashboard app that is quickly getting quite complex. I have over 1300 lines of code all sitting in app.R and it works. I'm using RStudio.
My application has a sidebar and tabs and rather than using modules I dynamically grab the siderbar and tab IDs to generate a unique identifier when plotting graphs etc.
I'm trying to reorganise it to be more manageable and split it into tasks for other programmers but I'm running into errors.
Working Code
My original code has a number of library statements and sets the working directory to the code location.
rm(list = ls())
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
getwd()
I then have a range of functions that sit outside the ui/server functions so are only loaded once (not reactive). These are all called from within the server by setting the reactive values and calling the functions from within something like a renderPlot. Some of them are nested, so a function in server calls a function just in regular app.R which in turn calls another one. Eg.
# Start of month calculation
som <- function(x) {
toReturn <- as.Date(format(x, "%Y-%m-01"))
return(toReturn)
}
start_fc <- function(){
fc_start_date <- som(today())
return(fc_start_date)
}
then in server something like this (code incomplete)
server <- function(input, output, session) {
RV <- reactiveValues()
observe({
RV$selection <- input[[input$sidebar]]
# cat("Selected:",RV$selection,"\r")
})
.......
cat(paste0("modelType: ",input[[paste0(RV$selection,"-modeltype")]]," \n"))
vline1 <- decimal_date(start_pred(input[[paste0(RV$selection,"-modeltype")]],input[[paste0(RV$selection,"-modelrange")]][1]))
vline2 <- decimal_date(start_fc())
.......
Problem Code
So now when I take all my functions and put them into different .R files I get errors indicating the functions haven't been loaded. If I load the source files by highlighting them and Alt-Enter running them so they are loaded into memory then click on Run App the code works. But if I rely on Run App to load those source files, and the functions within them, the functions can't be found.
source('./functionsGeneral.R')
source('./functionsQuote.R')
source('./functionsNewBusiness.R')
source('./ui.R')
source('./server.R')
shinyApp(ui, server)
where ui.R is
source('./header.R')
source('./sidebar.R')
source('./body.R')
source('./functionsUI.R')
ui <- dashboardPage(
header,
sidebar,
body
)
Finally the questions
In what order does R Shiny Dashboard run the code. Why does it fail when I put the exact same inline code into another file and reference it with source('./functions.R')? Does it not load into memory during a shiny app session? What am I missing?
Any help on this would be greatly appreciated.
Thanks,
Travis
Ok I've discovered the easiest way is to create a subfolder called R and to place the preload code into that folder. From shiny version 1.5 all this code in the R folder is loaded first automatically.

R Shiny select files from server-side directory

I have a folder called logs filled with different .csv files, formatted as telemetryLog-2017.21.08.54.11.csv (with varying dates and times at end).
For example, the above file could be stored like this: file <- read.csv("logs/telemetryLog-1969.2017.21.08.54.11.csv", header=TRUE)
The log files would be uploaded (in the logs folder, to shinyapps.io) along with the ui.R and server.R files. I would like to be able to obtain a list of the filenames in order to be able to select a file to display as data in a plot via selectInput (or any other way to list the files). The amount of files in the folder will not be an excessive amount; most likely it will be limited to around 50.
I have read the documentation for shinyFiles and to be completely honest I do not fully understand how the commands such as fileGetter or dirGetter work. Any help would be appreciated.
Instead of having people browse the file system of your server, you could also use list.files and specify the right directory there:
library(shiny)
ui <- fluidPage(
selectInput('selectfile','Select File',choice = list.files('log/')),
textOutput('fileselected')
)
server <- function(input,output)
{
output$fileselected <- renderText({
paste0('You have selected: ', input$selectfile)
})
}
shinyApp(ui,server)
Hope this helps!

Set www location in shiny::shinyApp

I am currently creating a shiny app that gets invoked with shiny::shinyApp via a wrapper function.
startApp <- function(param1, param2, ...){
# in fact, ui and server change based on the parameters
ui <- fluidPage()
server <- function(...){}
runApp(shinyApp(ui, server))
}
When I include resources (like images, videos etc.), I currently use the addResourcePath command and include the resources with a prefix. However, I would like to add a "default resource path" (appDir/www in usual apps). There seems to be no suitable parameter in shinyApp or runApp. Setting the working directory to the resource folder or one level above does not work either.
Here is a short MWE.
## ~/myApp/app.R
library(shiny)
shinyApp(
fluidPage(tags$img(src = "image.gif")),
server <- function(...){}
)
## ~/myApp/www/image.gif
# binary file
If I run the app via RunApp("~/myApp") everything works, but
setwd("~/myApp")
myApp <- shinyApp(source("app.R")$value)
runApp(myApp)
will fail to display the image. Any suggestions are appreciated.
Context
The reason I want to start the app based on an shiny.appobj (an object that represents the app) rather than a file path is, that the latter approach does not work well with passing parameters to an app. Here is a discussion about this topic.
The recommended way of passing parameters to an app that gets invoked by runApp("some/path") is as follows:
startApp <- function(param1, param2, ...) {
.GlobalEnv$.param1 <- param1
.GlobalEnv$.param2 <- param2
.GlobalEnv$.ellipsis <- as.list(...)
on.exit(rm(.param1, .param2, .ellipsis, envir = .GlobalEnv))
runApp("~/myApp")
}
This approach is just ugly IMO and I get warnings when I build the package that contains the app together with the startApp function. Those warnings occur because the package then breaks the recommended scoping model for package development.
In the help documentation in shiny::runApp, it says appDir could be either of the below:
A directory containing server.R, plus, either ui.R or a www directory
that contains the file index.html.
A directory containing app.R.
An .R file containing a Shiny application, ending with an expression
that produces a Shiny app object.
A list with ui and server components.
A Shiny app object created by shinyApp.
When you run via RunApp("~/myApp"), it is a directory containing app.R
If you want to run via a shiny app object created by shinyApp
you can try things like
myapp_obj <- shinyApp(
fluidPage(tags$img(src = "image.gif")),
server <- function(...){}
)
runApp(myapp_obj)
Update
create a script myapp_script.R with
shinyApp(
fluidPage(tags$img(src='image.gif')),
server <- function(...){}
)
and then call runApp("myapp_script.R")

Reading an RData file into Shiny Application

I am working on a shiny app that will read a few RData files in and show tables with the contents. These files are generated by scripts that eventually turns the data into a data frame. They are then saved using the save() function.
Within the shiny application I have three files:
ui.R, server.R, and global.R
I want the files to be read on an interval so they are updated when the files are updated, thus I am using:
reactiveFileReader()
I have followed a few of the instructions I have found online, but I keep getting an error "Error: missing value where TRUE/FALSE is needed". I have tried to simplify this so I am not using:
reactiveFileReader()
functionality and simply loading the file in the server.R (also tried in the global.R file). Again, the
load()
statement is reading in a data frame. I had this working at one point by loading in the file, then assigning the file to a variable and doing an "as.data.table", but that shouldn't matter, this should read in a data frame format just fine. I think this is a scoping issue, but I am not sure. Any help? My code is at:
http://pastebin.com/V01Uw0se
Thanks so much!
Here is a possible solution inspired by this post http://www.r-bloggers.com/safe-loading-of-rdata-files/. The Rdata file is loaded into a new environment which ensures that it will not have unexpected side effect (overwriting existing variables etc). When you click the button, a new random data frame will be generated and then saved to a file. The reactiveFileReader then read the file into a new environment. Lastly we access the first item in the new environment (assuming that the Rdata file contains only one variable which is a data frame) and print it to a table.
library(shiny)
# This function, borrowed from http://www.r-bloggers.com/safe-loading-of-rdata-files/, load the Rdata into a new environment to avoid side effects
LoadToEnvironment <- function(RData, env=new.env()) {
load(RData, env)
return(env)
}
ui <- shinyUI(fluidPage(
titlePanel("Example"),
sidebarLayout(
sidebarPanel(
actionButton("generate", "Click to generate an Rdata file")
),
mainPanel(
tableOutput("table")
)
)
))
server <- shinyServer(function(input, output, session) {
# Click the button to generate a new random data frame and write to file
observeEvent(input$generate, {
sample_dataframe <- data.frame(a=runif(10), b=rnorm(10))
save(sample_dataframe, file="test.Rdata")
rm(sample_dataframe)
})
output$table <- renderTable({
# Use a reactiveFileReader to read the file on change, and load the content into a new environment
env <- reactiveFileReader(1000, session, "test.Rdata", LoadToEnvironment)
# Access the first item in the new environment, assuming that the Rdata contains only 1 item which is a data frame
env()[[names(env())[1]]]
})
})
shinyApp(ui = ui, server = server)
Ok - I figured out how to do what I need to. For my first issue, I wanted the look and feel of 'renderDataTable', but I wanted to pull in a data frame (renderDataTable / dataTableOutput does not allow this, it must be in a table format). In order to do this, I found a handy usage of ReportingTools (from Bioconductor) and how they do it. This allows you to use a data frame directly and still have the HTML table with the sorts, search, pagination, etc.. The info can be found here:
https://bioconductor.org/packages/release/bioc/html/ReportingTools.html
Now, for my second issue - updating the data and table regularly without restarting the app. This turned out to be simple, it just took me some time to figure it out, being new to Shiny. One thing to point out, to keep this example simple, I used renderTable rather than the solution above with the ReportingTools package. I just wanted to keep this example simple. The first thing I did was wrap all of my server.R code (within the shinyServer() function) in an observe({}). Then I used invalidateLater() to tell it to refresh every 5 seconds. Here is the code:
## server.R ##
library(shiny)
library(shinydashboard)
library(DT)
shinyServer(function(input, output, session) {
observe({
invalidateLater(5000,session)
output$PRI1LastPeriodTable <- renderTable({
prioirtyOneIncidentsLastPeriod <- updateILP()
})
})
})
Now, original for the renderTable() portion, I was just calling the object name of the loaded .Rdata file, but I wanted it to be read each time, so I created a function in my global.R file (this could have been in server.R) to load the file. That code is here:
updateILP <- function() {
load(file = "W:/Projects/R/Scripts/ITPOD/itpod/data/prioirtyOneIncidentsLastPeriod.RData", envir = .GlobalEnv)
return(prioirtyOneIncidentsLastPeriod)
}
That's it, nothing else goes in the global.R file. Your ui.R would be however you have it setup, call tableOutout, dataTableOutput, or whatever your rendering method is in the UI. So, what happens is every 5 seconds the renderTable() code is read every 5 seconds, which in turns invokes the function that actually reads the file. I tested this by making changes to the data file, and the shiny app updated without any interaction from me. Works like a charm.
If this is inelegant or is not efficient, please let me know if it can be improved, this was the most straight-forward way I could figure this out. Thanks to everyone for the help and comments!

Shiny Uploading Issues

I am trying to publish an Shiny app at the moment but I am but after the deployment is completed an the app is loaded in the window, I get an error message of ERROR: object 'inData' not found.
In srcfile.R I am loading a .csv file which creates inData and then doing some analysis which I will use in Shiny to plot. This is my first time actually uploading an app to the server so I am unsure whether the issue is with the app really not finding the input inData or there is another error somewhere and this error message is thrown up. I have srcfile.R in the folder I uploaded as well as the .csv file that reads from.
library(shiny)
library(datasets)
library(ggplot2)
source("srcfile.R")
###########Shiny Starts here#########
shinyServer(function(input, output) {
options(scipen=5)
switcher <- function(x) {
if(x=="dis"){
#more code below of course.......
I have seen that relative pathways are always recommended but maybe I should try an absolute pathway.

Resources