首页 > 解决方案 > Shiny app can't access data if runApp is run from a .Rprofile

问题描述

I built a Shiny app that makes use of a list variable (for label customization) that is created from an excel file. The name of this variable is refvar

refvar is created into shinyServer() in server.R and is used to build UI elements that are sent to ui.R. refvar is also used by load.data(). load.data() is defined into global.R and used into shinyServer().

The odd thing is that if I run the app manually ("Run App" button in RStudio or runApp() from RStudio console) it works, while if I put shiny::runApp() in a .Rprofile file, to start the app as soon I open my RStudio project, I get the error "ERROR: object 'refvars' not found" in the browser.

Here's the (supposedly) relevant code

.Rprofile

    shiny::runApp()

server.R

    shinyServer(function(input, output) {

        refvars <- read_excel('Labels.xlsx') %>% dplyr::select(1:2) %>% set_colnames(c('Var', 'Label')) %>% mutate_all(str_squish) %>% spread(Var, Label) %>% as.list


        Data <- load.data()

        output$UI.report.sel.text <- renderUI({helpText(refvars$report.sel.text)})
        output$UI.daterange.sel.text <- renderUI({helpText(refvars$daterange.sel.text)})


        #[...]
    })

global.R

load.data <- function() {

    tryCatch(read_excel("Report_data.xlsx"), error = function(e) file.choose()) %>%
        rename(!!c(
            Anno = refvars$year,
            Mese = refvars$month,
            Indagine = refvars$report,
            Reparto = refvars$context,
            Note = refvars$notes,
            Problemi = refvars$problems,
            Sforamenti = refvars$non.compliance,
            Protocollo = refvars$id
        )) %>%
        mutate(
            Data = ymd(paste(Anno, Mese, '1', sep = '-'))
        )
}

UPDATE:

I made some experiments putting refvar in global.R. The app now starts well from the .Rprofile but some things are broken. For example where there should be a ggplot I get "ERROR: object 'title' not found", but actually I'm not using any title object.
I tried to inspect the status of the data I passed to ggplot via capture.output(str(Data)) and outputting it to ui.R via a uiOutput directive. The error became that it could find function str() and capture.output(); util package wasn't loaded!

So I suppose that the problem is that runApp() from .Rprofile run just too early. How can I fix this?

标签: rshinyinitializationrprofile

解决方案


问题完全在于运行.Rprofile时仍然没有加载默认包。

因此,我不得不重新定义 .First.sys 函数,在那里添加我的 runApp 代码:

.Rprofile

pkg.require <- function(pkgs, load = T){
    installed <- utils::installed.packages()

    not.installed <- c()

    for (pkg in pkgs) {
        if (!(pkg %in% installed)) not.installed <- c(not.installed, pkg)
    }

    if (length(not.installed) > 0) utils::install.packages(not.installed)

    if (load) for (pkg in pkgs) library(pkg, character.only = TRUE)
}


.First.sys <- function () 
{
    for (pkg in getOption("defaultPackages")) {
        res <- require(pkg, quietly = TRUE, warn.conflicts = FALSE, 
            character.only = TRUE)
        if (!res) 
            warning(gettextf("package %s in options(\"defaultPackages\") was not found", 
                sQuote(pkg)), call. = FALSE, domain = NA)
    }

    pkg.require(c('shiny'))

    shiny::runApp(launch.browser = T)
}

推荐阅读