You could use my Ramd package that was designed for this. First devtools::install_github('robertzk/Ramd')
. Now you can include arbitrary scripts (in the same "asynchronous modular dependencies" format you see in node.js projects):
ui.r
library(Ramd)
define('public_data', function(public_data) {
shinyUI( navbarPage("Synodos Data Explorer", id="nav",
public_data, kinome_screens
))
})
public_data.r
tabPanel("Public Data",
titlePanel("Explore Public Datasets"),
source("code1.R")
)
kinome_screens.r
tabPanel("Kinome Screens",
titlePanel("Exploring Kinome Screening Data"),
source("code2.R")
)
Explanation
The define
function allows you to include R scripts relative to the directory the currently executing file lives in. For example, if you would like to structure your code into a directory format, you could do:
define('dir/some_file', 'dir2/some_other_file', function(one, two) {
# You can use one and two, the "return value" (last expression) in the
# above files
})
Note that proper use of this completely eliminates the use of global variables and will solve both your managing global state and code organizational issues. The main trick behind this is that when you source a file, like this:
# test.r
c(1,2,3) # This will be ignored, since it isn't at the end of the file
list(1, "hello!")
# otherfile.r
x <- source('test.r')$value
Then x
is now list(1, "hello!")
(in particular, the "return value" of a call to base::source
like this will always give the last expression in the file. Everything you want to pass to other files that include this file should be wrapped up at the end, possibly in a list if you want to return multiple things. You can use this to hierarchically nest your complex Shiny project in a sane organizational structure.
Here is a complete working example that illustrates how to structure some code in a directory with Ramd:
### main.r
define('blah/foo', 'blah2/faa', function(one, two) {
print(one + two)
})
### blah/foo.r
x <- 1
y <- 2
x + y
### blah2/faa.r
z <- 1
w <- 5
w - z
### R console
library(Ramd); source('main.r')
# [1] 7