[Rd] surprising behaviour of names<-
Peter Dalgaard
P.Dalgaard at biostat.ku.dk
Tue Mar 10 16:10:49 CET 2009
Wacek Kusnierczyk wrote:
> playing with 'names<-', i observed the following:
>
> x = 1
> names(x)
> # NULL
> 'names<-'(x, 'foo')
> # c(foo=1)
> names(x)
> # NULL
>
> where 'names<-' has a functional flavour (does not change x), but:
>
> x = 1:2
> names(x)
> # NULL
> 'names<-'(x, 'foo')
> # c(foo=1, 2)
> names(x)
> # "foo" NA
>
> where 'names<-' seems to perform a side effect on x (destructively
> modifies x). furthermore:
>
> x = c(foo=1)
> names(x)
> # "foo"
> 'names<-'(x, NULL)
> names(x)
> # NULL
> 'names<-'(x, 'bar')
> names(x)
> # "bar" !!!
>
> x = c(foo=1)
> names(x)
> # "foo"
> 'names<-'(x, 'bar')
> names(x)
> # "bar" !!!
>
> where 'names<-' is not only able to destructively remove names from x,
> but also destructively add or modify them (quite unlike in the first
> example above).
>
> analogous code but using 'dimnames<-' on a matrix performs a side effect
> on the matrix even if it initially does not have dimnames:
>
> x = matrix(1,1,1)
> dimnames(x)
> # NULL
> 'dimnames<-'(x, list('foo', 'bar'))
> dimnames(x)
> # list("foo", "bar")
>
> this is incoherent with the first example above, in that in both cases
> the structure initially has no names or dimnames attribute, but the end
> result is different in the two examples.
>
> is there something i misunderstand here?
Only the ideology/pragmatism... In principle, R has call-by-value
semantics and a function does not destructively modify its arguments(*),
and foo(x)<-bar behaves like x <- "foo<-"(x, bar). HOWEVER, this has
obvious performance repercussions (think x <- rnorm(1e7); x[1] <- 0), so
we do allow destructive modification by replacement functions, PROVIDED
that the x is not used by anything else. On the least suspicion that
something else is using the object, a copy of x is made before the
modification.
So
(A) you should not use code like y <- "foo<-"(x, bar)
because
(B) you cannot (easily) predict whether or not x will be modified
destructively
--------
(*) unless you mess with match.call() or substitute() and the like. But
that's a different story.
--
O__ ---- Peter Dalgaard Øster Farimagsgade 5, Entr.B
c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K
(*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
More information about the R-devel
mailing list