2015-09-09 5 views
3

J'essaie d'accéder à un objet (a<-get(obj1,envir=parent.environment())) résidant dans l'environnement appelant à partir de l'environnement appelé myf et je n'arrive pas à le faire fonctionner. Erreur que je reçois est Object obj1 not found. J'ai aussi essayé parent.frame(). Des idées?R shiny 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 = ",")) 
    }) 
    } 
) 

NOTE: Je ne veux pas créer obj1 à l'aide obj1<<- car elle crée dans l'environnement mondial et est disponible pour toutes les sessions

Répondre

5

La bonne solution est que vous avez trois problèmes: tout d'abord, vous devez citer "obj1" comme celui-ci

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

Deuxièmement, parent.environment() n'est pas une fonction. Cela n'existe pas. Troisièmement, vous devez comprendre un peu l'environnement et les cadres d'appel pour savoir comment cela fonctionne (cela n'a rien à voir avec Shiny). Ce que vous voulez utiliser est parent.frame(2) (être à l'intérieur d'une lapply ajoute une couche)

Donc, pour modifier votre code d'origine, c'est la solution:

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

Bon, je n'ai même pas remarqué que '" obj1 "' n'était pas cité. Pas étonnant! – shadowtalker

+0

Je l'ai seulement remarqué quand j'ai corrigé le problème de parent.environment pour être l'environnement correct, et recevais toujours l'erreur, et ai pensé "mais je suis dans le bon env ..... pourquoi!" "ah .." –

+0

Génial, merci pour l'explication détaillée 'daattali'. Je devrais en savoir plus sur l'appel des cadres - de bons liens? – Sri

1

Je ne sais pas pourquoi cela ne fonctionne pas, mais il y a un solution de contournement simple: passer explicitement 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

Merci pour la solution de contournement, vous avez également la solution la portée trop - Je suis intéressé de voir quelle est la solution de délimitation de la portée? – Sri

+0

"Je ne sais pas pourquoi cela ne fonctionne pas" – shadowtalker

+1

Vous pouvez voir ma réponse pour voir la solution correcte plutôt qu'une solution de contournement –