gsubfn scoping

27 views
Skip to first unread message

hol...@thebutlerfirm.com

unread,
Jun 20, 2015, 4:55:01 AM6/20/15
to sq...@googlegroups.com
Hey Gabor,

Thanks for your work, I had been looking for a good and reliable variable replacement function and found it in gsubfn. I'm a little confused by the scoping.

I could be mistaken but it looks like it's not taking parent.frame() as the default environment. So when I want to have gsubfn() inside a function, I have to explicitly define env = parent.frame(). E.g.,

library(gsubfn)
formals(gsubfn)$env #= parent.frame()
# default env
gsubAT <- function(string) {return(gsub("@","",gsubfn(x=string)))}
replaceTest <- function(variable) {return(gsubAT("The variable is $variable@"))}
replaceTest("test") #Error in eval(expr, envir, enclos) : object 'variable' not found
# env = environment()
gsubAT <- function(string) {return(gsub("@","",gsubfn(x=string,env=environment())))}
replaceTest <- function(variable) {return(gsubAT("The variable is $variable@"))}
replaceTest("test") #Error in eval(expr, envir, enclos) : object 'variable' not found
# env = parent.frame()
gsubAT <- function(string) {return(gsub("@","",gsubfn(x=string,env=parent.frame())))}
replaceTest <- function(variable) {return(gsubAT("The variable is $variable@"))}
replaceTest("test") #Works
# using replacement
gsubAT <- function(string,variables) {return(gsub("@","",gsubfn(x=string,replacement=variables)))}
replaceTest <- function(variables) {return(gsubAT("The variable is $variable@",variables=variables))}
replaceTest(list(variable="test")) #Works

I suppose the last version is best? Thanks.

Chris

Gabor Grothendieck

unread,
Jun 20, 2015, 5:22:51 AM6/20/15
to sq...@googlegroups.com, hol...@thebutlerfirm.com, hol...@thebutlerfirm.com
The default environment used by gsubfn to find variables is env = parent.frame(), i.e. the function calling it.  In the example below taken from your post, gsubfn is called from gsubAT so the environment within gsubAT is the parent.frame.  There is no variable called `variable` there so we get an error.

   gsubAT <- function(string) {return(gsub("@","",gsubfn(x=string)))} 
   replaceTest <- function(variable) {return(gsubAT("The variable is $variable@"))} 
   replaceTest("test") 

giving:

   Error in eval(expr, envir, enclos) : object 'variable' not found 

The problem here is not with gusbfn which does properly pass the environment through the env= argument but with gsubAT which does not.  If you add an env= argument to gsubAT then it works::

   gsubAT <- function(string, env = parent.frame()) {return(gsub("@","",gsubfn(x=string, env = env)))}  # modified

   replaceTest <- function(variable) {return(gsubAT("The variable is $variable@") )}
   replaceTest("test") #Error in eval(expr, envir, enclos) : 

giving:

   [1] "The variable is test"
Reply all
Reply to author
Forward
0 new messages