R闪亮对象范围

R shiny object scoping

我正在尝试从被调用环境 myf 访问驻留在调用环境中的对象 (a<-get(obj1,envir=parent.environment())),但我无法使其正常工作。我得到的错误是 Object obj1 not found。我也试过parent.frame()。有什么想法吗?

library(shiny)
shinyApp(
  ui = textOutput("test1"),
  server = function(input, output) {
    myf <- function(x) {
      a <- get(obj1, envir = parent.environment())
      return(paste0(x,a))
    }
    output$test1 <- renderText({
      obj1 <- "testing"
      a <- lapply(c("a","b","c"), myf)
      return(paste(unlist(a), collapse = ","))
    })
  }
)

注意:我不想使用 obj1<<- 创建 obj1,因为它在全局环境中创建并且可用于所有会话

我不确定为什么它不起作用,但有一个简单的解决方法:明确地将 obj1 传递给 myf:

library(shiny)
shinyApp(
  ui = textOutput("test1"),
  server = function(input, output) {

## myf now takes two arguments, x and a:
    myf <- function(x, a) {
      return(paste0(x, a))
    }

    output$test1 <- renderText({
      obj1 <- "testing"

## Now you can just pass obj1 as a second argument to myf
##  without worrying about scoping:
      a <- lapply(c("a","b","c"), myf, obj1)

      return(paste(unlist(a), collapse = ","))
    })
  }
)

正确的解决办法是你遇到了三个问题: 首先,你需要这样引用"obj1"

get("obj1", envir = ...)

其次,parent.environment()不是函数。它不存在。

第三,你需要稍微了解环境和调用框架,才能知道它是如何工作的(与Shiny无关)。您要使用的是 parent.frame(2)(在 lapply 内添加一层)

所以要修改你的原始代码,这是解决方案:

library(shiny)
shinyApp(
  ui = textOutput("test1"),
  server = function(input, output) {
    myf <- function(x) {
      a <- get("obj1", envir = parent.frame(2))
      return(paste0(x,a))
    }
    output$test1 <- renderText({
      obj1 <- "testing"
      a <- lapply(c("a","b","c"), myf)
      return(paste(unlist(a), collapse = ","))
    })
  }
)