rshinyr-packageworking-directory

getwd() returns non-existent directory in Shiny app


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?


Solution

  • 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) {
        ns <- topenv()
        ns$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))