R Shiny:作为应用程序运行时,为什么源文件中的函数无法访问全局变量?

Wol*_*lff 4 r global-variables shiny

我已经构建了一个几乎完成的闪亮仪表板。

我有多个包含各种函数的源文件,其中一些引用了主 R 代码中定义的全局变量,而不直接将它们作为参数传递。

我一直在构建它并通过运行代码段来测试/调试它,并手动运行shinyapp函数来启动它。当我这样做时,应用程序按预期工作。源文件中的函数可以读取全局变量。

但是,当我清除工作区并保存代码并使用“运行应用程序”功能一次运行整个过程时,它会失败,因为源文件函数无法再找到全局变量,即使创建这些变量的代码在全局环境中位于调用这些函数的任何代码之前。

请注意,如果我已经手动运行创建全局变量的代码部分并在不清除工作区的情况下运行应用程序,则函数可以读取它们。

有谁知道这是为什么,以及我该如何解决它?

在下面的可重现示例中,全局变量被赋予值“Hello_World”。函数 test_function() 只是返回全局变量的值,然后将其用作 UI 中的标题。

主要R代码

# Import packages.
library(shiny)
library(shinydashboard)
library(DT)
library(data.table)
library(tidyverse)
library(dtplyr)


# Global Variables
global_var <- "Hello_World"

# Directory
directory <- ''

# Source function stored in separate file.
source(paste0(directory,"Test Function.R"))

# UI
ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    sidebarMenu(
      id = "tabs",
      menuItem("Test", tabName="tab_data",icon=icon("table"))
    )
  ),
  dashboardBody(
    tabItem("tab_data",
                  fluidPage(
                    fluidRow(column(width=12,
                                    h4(test_function())
                    ))
                  )
            )
    )
)

# Server
server <- function(input, output, session) {
}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

“测试功能.R”

test_function <- function(){
  return(global_var)
}
Run Code Online (Sandbox Code Playgroud)

您需要在主目录中将它们创建为两个文件。代码原样失败并抛出错误:

Error in test_function() : object 'global_var' not found
Run Code Online (Sandbox Code Playgroud)

如果我将代码的最后一行更改为以下内容,则允许代码分段手动运行。如果我突出显示整个代码并运行它,它就会起作用。“Hello_World”显示为标题。

if(1==1){shinyApp(ui, server)}
Run Code Online (Sandbox Code Playgroud)

现在,如果我改回该语句,那么全局变量已经由上次运行创建,并将其作为应用程序运行,它就可以工作。

我需要让它做的是让源函数能够在工作区清除时从第一次运行中读取全局变量。

r2e*_*ans 6

前面:使用source("...", local = TRUE).

source默认情况下将文件加载到全局环境中,而不是本地环境中。当您在控制台上工作时,两者是相同的。但是,当您运行应用程序时,应用程序的环境是不同的,并且不在全局环境中定义的函数的搜索路径中。

例子:

当来源时,我看到

# Error in func() (from quux.R#2) : object 'global_var' not found
Run Code Online (Sandbox Code Playgroud)

即,

environment(func)
# <environment: R_GlobalEnv>
Run Code Online (Sandbox Code Playgroud)

当我将主文件更改为

global_var <- "Hello"
source("quux.R", local = TRUE)
Run Code Online (Sandbox Code Playgroud)

然后采购它就可以了,就像func()它本身一样。

environment(func)
# <environment: 0x0000000054a995e0>
func()
# [1] "Hello"
Run Code Online (Sandbox Code Playgroud)