Have shiny load from a file not named app.R - r

Does anyone know i it is possible to change the default file that shiny loads?
I was hoping for a bit more flexibility than one file per directory.

It depends on your setup.
Setup 1: Run app locally from a file
If you want to run an application locally (inside an interactive R session) you can use the command
shiny::shinyAppFile("path/to/my/appFile.R")
to load an application. The app file does not have to be named app.R in that case. Note however that with this approach all relative paths (for example image paths) will be resolved relative to your working directory rather than relative to the app's directory.
Setup 2: Run app on a server
If the app shold be run via shiny-server (or shinyapps.io) things are more complicated. In this case the server will expect the app to be defined either as app.R or ui.R/server.R in order to be loaded properly. The only workaround I am aware of here is to use shinyAppFile inside app.R but this might not be very useful in most situations.
Setup 3: Define the app as an object
You can also define an app as an R object and invoke it by printing the object.
someAppObj <- shinyApp(ui = fluidPage(), server = function(...) {})
## start the app by printing it
someAppObj
As mentioned in the answer of #ismirsehregal, you can also use runApp instead of the printing method which will take care if relative paths and handle the app-environment slightly differently.
runApp(someAppObj)
Setup 1 is actually related to setup 3 since since shinyAppFile returns an app-object.

For a single file app just rename it and add
app <- shinyApp(ui = ui, server = server)
runApp(app)
to be able to source it.

Related

Best way to distribute an R/Shiny app to be run by a user on local computer?

I have developed a Shiny app for a user at a different location. This app may eventually be hosted in the cloud but for now a single user will run the application locally on their computer. What is the preferred way to share the application and also make it easy to maintain/update the scripts?
Do I need to instruct the user to install R, RStudio, all of the packages used by the application, and copy the R scripts, etc, to a local directory, and then include directions about how to run from the RStudio interface?
I'm intrigued by the runGitHub option, which seems very appealing, with one problem: It wouldn't be wise to add the file containing API tokens in the GitHub repository. Is there a way for the code to look for that specific file locally instead of in the repository?
Thank you!
You can use {dotenv} to store the secrets. For example,
create a .env in your app root folder.
In the file
username=xxxxxx
token="xxxxxx"
Make a copy of this file called .env-template.
Add .env but not .env-template to .gitignore.
Fill your real tokens in .env since this file will not be uploaded to github.
In R, use
# load secrets
library(dotenv)
load_dot_env('.env')
# to get values
Sys.getenv("username")
Sys.getenv("token")
Tell users to fill their real tokens in .env-template and rename it to .env
to use runGithub or runGist
The demo is very simple, just to get the secret token locally while running app from a remote address.
Your app code
library(shiny)
server <- function(input, output, session) {
print(Sys.getenv("token")) # just print out the token on console
}
shinyApp(div(), server)
User code will be like
library(shiny)
### first run without following 4 lines and then uncomment following and run again
### watch the difference on console
# library(dotenv)
# dotenv_file <- tempfile()
# cat('token=12345', file = dotenv_file)
# load_dot_env(dotenv_file)
###
runGist('https://gist.github.com/lz100/f54d59901a56a051770edd77e1324f21')

Calling global.R in an app.R file on shiny server; unable to call dataframes in for global use

I am developing a shiny app which is an exploratory data analysis tool. At this point, I am trying to optimise so that data is loaded in once but is readily available for all users. I am aware of the scoping materials on this i.e. Scoping I have the code to load the data in for the app within a global.R file like so:-
#global.R file
library(feather)
dataframe1<-read_feather("df1.feather")
dataframe2<-read_feather("df2.feather")
These are the dataframes that I need to call once and make available to all users of the app. However, I am calling the ui and the server code all within app.R and I have a hunch that this could be problematic.
I have tried a few implementations as guided by what I have been able to see on the web but it is obvious that I am not doing something properly. Here are some examples of what I have tried
source('global.R', local = T)
ui<-fluidPage({
#code for ui
})
server<-function(input,output,server){
# code for server
}
shinyApp(ui,server)
Where the outcome is this:-
The second thing I have tried is having the global file called in onStart parameter in the shinyApp(), but I have the same error.
The global file is saved in the GitLab repo that I am using to deploy this app on shiny server. The app.R script Can any one show me how I can correctly call the global.R file, so that the data is loaded in once and made available to all users of the app? Do I need to split the app.R file into a ui.R and a server.R file?

Change the directory of a file to be saved

I have a shiny app that I deployed as a library. Inside my shiny app, I write a json file in real time, I want to write this file in the working directory of each user. Nevertheless, the file is written in the directory of the library.(Please refer the code below)
app.R
library(Tree)
ui <- htmlTemplate("www/Tree.html",
text_output = tableOutput("table2")
)
server <- function(input, output, session){
# This block fires each time we receive a message from JavaScript
output$table2 <- renderTable({
#Write json file
json_value = input$jsonData
write(json_value, paste0(getwd(),"/",fileName, ".json"))
})
}
# Run the application
shinyApp(ui , server)
I though that with the function getwd()I will be able to see my json file in my working directory but taht is not happening. My json file is written in the directory of the library
This directory
/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Tree/
How can I change my code to be able to see my jsonfile in the RProject which the user wants to work?
A shiny app is running in your browser and, as a concequence, subject to strict safety regulations imposed by the browser. There are plenty of restrictions regarding the file system to make sure that web pages cannot freely roam your hard drive. That is why there might not be a solution with a good user experience to achieve what you want.
The safest solution would be the download button (as suggested by #HubertL).
If you want to work with the users' home directory you can get the path with file.path(Sys.getenv("HOME")) (at least on Windows it works). Now you can work with that path. Use OutputPath <- file.path(Sys.getenv("HOME"), fileName) to create the path %HOME%/fileName.
The third alternative (I can think of) is a simple textInput. Users can paste a string there that represents the path to the directory where they want the file to be stored. Check the string with dir.exists and use it if it is valid.

global.R don't start

I'm wondering why global.R doesn't start when i launch my app from Rstudio.
It seems, of what i understood, that global.R must be run once as i launch my app, but instead Rstudio give me an error that it could not find the function that i have defined in the global.R file.
After running global.R by hand with ctl+alt+r then i can launch my app and it recognize the function and works well all during the time i use the R session. I'm not publishing on the web but works just in local.
Do i missed something?
Thanks.
(R version 3.5.2 and shiny 1.2)
The content of global.R is usable only if the shiny app is made of server.R and ui.R. The content of global.R is ignored if the app is made of a unique app.R file.
Splitting your app.R in server.R and ui.R will
resolve your issue.
Since the OP asked about why global.R is not read when the architecture relies only a single app.R, it is because of how the app is started.
If it is started via:
shinyApp(ui = ui, server = server)
Then the application is considering these two functions without running anything beforehand, i.e. neglecting global.R contents. There is, however, the onStart parameter that can be supplied to shinyApp to run something before the app starts, and its description resolves a great deal of confusion:
onStart: A function that will be called before the app is actually run. This is only needed for shinyAppObj, since in the shinyAppDir case, a global.R file can be used for this purpose.
It looks to me that when the application is split into server.R and ui.R, global.R is automatically included by means of running the app through shinyAppDir.
The solutions I found in case one wants to strictly use a single app.R code file and perform some routines prior to starting the app are:
Tinker with onStart parameter inside shinyApp call
Source global.R as #tic-toc-choc points out

Running shiny server app with additional r files

I have 3 files which are needed to my app.
First a general r with functions make some calculations and need to load the ui and server files to run the app.
When I run it on Rstudio it works fine. How is it possible to insert this app to shiny server, meaning that I need first a script and after that run the ui and server files?
Use a global.R file or use source(file, local = FALSE) to read R Code from a file.
For more details check the scoping rules.

Resources