I have the following Shiny package:
DESCRIPTION
:
Package: mypackage
Version: 0.0.1
Depends: shiny
R/mypackage.R
:
ui <- shiny::fluidPage(getwd())
server <- function(input, output, session) {}
To install and run, I do
R -q -e "devtools::install(); shiny::runApp(shinyApp(mypackage:::ui, mypackage:::server))"
And when I do this, my app outputs
/tmp/RtmpC1viCa/R.INSTALL6931e8be933/mypackage
which does not exist.
Why is that, and how I improve that? I have seen that getwd()
may not actually return the users working directory - but why is it returning a non-existent one?
CodePudding user response:
Inside a Shiny app, getwd()
refers to the application directory.
However, since you are creating a package, you need to be aware of, and careful about, where/when code is executed.
Code at file scope inside a package is executed at installation time. And installation of R packages happens inside a temporary directory to isolate it. In fact, R CMD check
will warn you about this.
If you need the value of getwd()
(as well as other path specific functions such as system.file
), you mustn’t call it at file scope.
The solution is to use the .onLoad
package hook. In your case, you need to create and assign the entire UI at package load time:
.onLoad <- function (libname, pkgname) {
assign(
'ui',
shiny::fluidPage(getwd()),
topenv()
)
}
If you dislike using assign
, $<-
also works:
.onLoad <- function (libname, pkgname) {
topenv()$ui <- shiny::fluidPage(getwd()),
}
But alternatively you could also create a function that returns the UI:
ui <- function () {
shiny::fluidPage(getwd())
}
And run it via
shiny::runApp(shinyApp(mypackage:::ui(), mypackage:::server))