2015-09-09 2 views
3

Я пытаюсь получить доступ к объекту (a<-get(obj1,envir=parent.environment())), находящемуся в вызывающей среде из вызываемой среды myf, и я не могу заставить его работать. Ошибка, которую я получаю, - Object obj1 not found. Я тоже попробовал parent.frame(). Есть идеи?R sciny object scoping

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<<-, поскольку он создает в глобальной окружающей среде и доступен для всех сеансов

ответ

5

правильное решение является то, что у вас есть три проблемы: Во-первых, вам нужно процитировать "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 = ",")) 
    }) 
    } 
) 
+0

Yikes, я даже не заметил, что '' obj1 "' не цитировался. Неудивительно! – shadowtalker

+0

Я заметил это только тогда, когда исправил проблему parent.environment как правильную среду и все еще получал ошибку, и подумал: «Но я в правильном env ..... почему!» «ах ..» –

+0

Удивительно, спасибо за подробное объяснение 'daattali'. Я должен больше узнать о вызовах фреймов - каких-либо хороших ссылок? – Sri

1

Я не знаю, почему он не работает, но есть»а простой обходной путь: явно передать 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 = ",")) 
    }) 
    } 
) 
+0

Спасибо за обходного, вы также обзорный решение слишком - Мне интересно посмотреть, что такое обзорное решение? – Sri

+0

«Я не уверен, почему это не работает» – shadowtalker

+1

Вы можете увидеть мой ответ, чтобы увидеть правильное решение, а не обходное решение –