[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