I would like to run R code in two locations, in an Rnw file and as an interactive shiny R markdown document.
Thus, what I need, since interactive shiny components do not work in Rnw files, is a code snippet in R that detects whether to load the interactive code or not.
This seems to work, but it feels like a quick hack:
if (exists("input")) { # input is provided by shiny
# interactive components like renderPlot for shiny
} else {
# non-interactive code for Rnw file
}
Is there a stable solution or something like a global variable that I can access that says whether shiny is running at the moment? Or should I check whether the shiny
package is loaded?
What's safest?
This information is provided directly via Shiny’s isRunning
function.
Outdated answer below:
You can do the following:
shiny_running = function () {
# Look for `runApp` call somewhere in the call stack.
frames = sys.frames()
calls = lapply(sys.calls(), `[[`, 1)
call_name = function (call)
if (is.function(call)) '<closure>' else deparse(call)
call_names = vapply(calls, call_name, character(1))
target_call = grep('^runApp$', call_names)
if (length(target_call) == 0)
return(FALSE)
# Found a function called `runApp`, verify that it’s Shiny’s.
target_frame = frames[[target_call]]
namespace_frame = parent.env(target_frame)
isNamespace(namespace_frame) && environmentName(namespace_frame) == 'shiny'
}
Now you can simply use shiny_running()
in code and get a logical value back that indicates whether the document is run as a Shiny app.
This is probably (close to) the best way, according to a discussion on Shiny the mailing list — but do note the caveats mentioned in the discussion.
Adapted from code in the “modules” package.
Alternatively, the following works. It may be better suited for the Shiny/RMarkdown use-case, but requires the existence of the YAML front matter: It works by reading the runtime
value from that.
shiny_running = function ()
identical(rmarkdown::metadata$runtime, 'shiny')