I have built a Shiny dashboard which is nearly complete.
I have multiple source files containing various functions, some which reference global variables which are defined in the main R code, without being passed them as arguments directly.
I have been building it and testing/debugging it by running segments of code, and manually running the shinyapp function to launch it. When I do this, the app works as expected. The functions from the source files can read the global variables.
However, when I clear the workspace and save the code and use the "Run App" feature to run the whole thing at once, it fails because the source file functions can no longer find the global variables, even though the code which creates these variables in the global environment comes before any code which calls these functions.
Note that if I've already run the section of code manually that creates the global variables and run the app without clearing the workspace, the functions are able to read them.
Does anyone know why this is, and how I can get around it?
In the reproducible example below, the global variable is given the value "Hello_World". The function test_function() simply returns the value of the global variable which is then used as a heading in the UI.
MAIN R CODE
# Import packages.
library(shiny)
library(shinydashboard)
library(DT)
library(data.table)
library(tidyverse)
library(dtplyr)
# Global Variables
global_var <- "Hello_World"
# Directory
directory <- ''
# Source function stored in separate file.
source(paste0(directory,"Test Function.R"))
# UI
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Test", tabName="tab_data",icon=icon("table"))
)
),
dashboardBody(
tabItem("tab_data",
fluidPage(
fluidRow(column(width=12,
h4(test_function())
))
)
)
)
)
# Server
server <- function(input, output, session) {
}
shinyApp(ui, server)
"TEST FUNCTION.R"
test_function <- function(){
return(global_var)
}
You will need to create these as two files in the home directory. The code as it is fails and throws the error:
Error in test_function() : object 'global_var' not found
If I change the last line of the code to the following, it allows the code to be run manually in segments. If I highlight the whole code and run it, it works. "Hello_World" is shown as the heading.
if(1==1){shinyApp(ui, server)}
Now if I change that statement back, now that the global variable is already created by the previous run, and run it as an app, it works.
What I need to be able to get it to do is for the source functions to be able to read the global variables from the first run when the workspace is clear.
Up front: use source("...", local = TRUE)
.
source
by default loads the file into the global environment, not the local environment. When you're working on your console, the two are the same. However, when you run the app, the app's environment is distinct, and not in the search-path for functions defined in the global environment.
Example:
main file:
global_var <- "Hello"
source("quux.R")
quux.R
:
func <- function() {
return(global_var)
}
When sourced, I see
# Error in func() (from quux.R#2) : object 'global_var' not found
Namely,
environment(func)
# <environment: R_GlobalEnv>
When I change the main file to
global_var <- "Hello"
source("quux.R", local = TRUE)
then sourcing it works, as does func()
by itself.
environment(func)
# <environment: 0x0000000054a995e0>
func()
# [1] "Hello"