[R] Change global env variables from within a function

Duncan Murdoch murdoch.duncan at gmail.com
Wed Oct 13 20:28:06 CEST 2010


  On 13/10/2010 2:19 PM, Jon Zadra wrote:
>    Hi,
>
> I've looked all over for a solution to this, but haven't had much look
> in specifying what I want to do with appropriate search terms.  Thus I'm
> turning to R-help.
>
> In the process of trying to write a simple function to rename individual
> column names in a data frame, I ran into the following problem: When I
> rename the columns within my function, I can't seem to get it to apply
> to the data frame in the global environment in a simple manner.
>
> Given:
>
> tempdf<- data.frame("a" = 1:6, "b" = 7:12)
>
> #I can rename a to g this way:
> names(tempdf)[names(tempdf)=="a"]<- "g"
>
> #Wanting to simplify this for the future, I have the function:
> colrename<- function(dframe, oldname, newname) {
>       names(dframe)[names(dframe)==oldname]<- newname
>       }
>
> colrename(tempdf, "a", "g")
>
> #However of course the change to tempdf stays within colrename().  I
> could add "return(names(dframe))" to the function and then call the
> function like:
> #names(tempdf)<- colrename(tempdf, "a", "g")
> #but at that point its not much simpler than the original:
> #names(tempdf)[names(tempdf)=="a"]<- "g"
>
> So, i'm wondering, is there a way to write code within that function so
> that the tempdf in the global environment gets changed?
> I thought of doing "names(dframe)[names(dframe)==oldname]<<- newname"
> but then of course it doesn't replace "dframe" with "tempdf" in the
> evaluation, so it seems to be a problem of looking at some variables
> within the function environment but others in the parent environment.
>
> Any help is greatly appreciated.


Make the changes to a local copy, then save it to the global (or just 
return the local copy as the value of the global).  For example,

colrename<- function(dframe, oldname, newname) {
      names(dframe)[names(dframe)==oldname]<- newname
      dframe
      }

called as

tempdf<- colrename(tempdf, "a", "g")

or if you really want to mess with things that don't belong to your function,



colrename<- function(dframe, oldname, newname) {
      name<- deparse(substitute(dframe))
      names(dframe)[names(dframe)==oldname]<- newname
      assign(name, dframe, env=globalenv())
      }



(but watch out if you call this with something other than a simple 
variable name as the first argument).

Duncan Murdoch



More information about the R-help mailing list