[R] side-effects in functions that replace object values and attributes

Stephen Tucker brown_emu at yahoo.com
Wed Feb 17 02:31:45 CET 2010


Hello list,

I encountered some surprising behavior in R and wanted to check to see if I was imagining things. Previously, I thought that replacement/setter operators in prefix notation (e.g., `[<-`(x,1,y) rather than x[1] <- y) did not produce side effects (i.e., left 'x' unchanged), but just realized that this is not the case anymore (or has it always been this way? - I don't have access to old R distributions at the moment, but using R 2.10.1 on Ubuntu and OS X)? I went through the NEWS file but did not see a change documented if there was one, but just going by my recollection...

In any case, my understanding was that when modifying a value or attribute of an object, R reassigned the modified object to the original symbol. For instance, the help file for `name<-`() says that 

> names(z)[3] <- "c2"

is evaluated as

> z <- "names<-"(z, "[<-"(names(z), 3, "c2"))

But the final (re)assignment (`<-`) seems redundant as 

> invisible("names<-"(z, "[<-"(names(z), 3, "c2")))

does the same thing.

In this case, I wonder if there is a preferred way to use the replacement/setter operators in prefix notation without producing such side effects (replace() exists for `[<-`() and `[[<-`(), but perhaps something more general). For instance, if I did not desire the following modification in x:

> x <- c("1","2")
> y <- `names<-`(x,c("a","b"))
> y
  a   b 
"1" "2" 
> x
  a   b 
"1" "2" 
> 

I might take advantage of R's lazy evaluation and use create a copy in the local function environment and allow that copy to be modified:

> x <- c("1","2")
> y <- `names<-`(`<-`(x,x),c("a","b"))
> y
  a   b 
"1" "2" 
> x
[1] "1" "2"

The interesting thing is that `mode<-`(), while also a "setter" function in that it sets an object attribute, does not behave as `names<-`():

> x <- c("1","2")
> y <- `mode<-`(x,"integer")
> y
[1] 1 2
> x
[1] "1" "2"
> mode(x)
[1] "character"

So another question that naturally arises is whether there a general rule by which we can predict the behavior of these types of operators (whether they produce side effects or not)?

Thanks,

Stephen



More information about the R-help mailing list