Skip to content

learning R

6 messages · Fuchs Ira, David Winsemius, Wacek Kusnierczyk

#
I was wondering why the following doesn't work:

 > a=c(1,2)
 > names(a)=c("one","two")
 > a
one two
   1   2
 >
 > names(a[2])
[1] "two"
 >
 > names(a[2])="too"
 > names(a)
[1] "one" "two"
 > a
one two
   1   2

I must not be understanding some basic concept here.
Why doesn't the 2nd name change to "too"?

also unrelated:  if I have two vectors and I want to combine them to  
form a matrix ,is cbind (or rbind) the most direct way to do this?

e.g.

x=c(1,2,3)
y=c(3,4,5)
z=rbind(x,y)

alternatively: is there a way to make a matrix with dim=2,3 and then  
to replace the 2nd row with y

something like this (which doesn't work but perhaps there is another  
way to do the equivalent?)

attr(x,"dim")=c(2,3)
x[2,]=y
#
On Feb 24, 2009, at 11:36 PM, Fuchs Ira wrote:

            
I cannot tell you why, perhaps you are not actually working with the  
names of a, but I can show you that:

 > names(a)[2] <- "too"
 > a[2]
too
   2
 > a
one too
   1   2

And this is seen as well in the help page examples. The help page also  
says the following, which I cannot understand:

It is possible to update just part of the names attribute via the  
general rules: see the examples. This works because the expression  
there is evaluated as z <- "names<-"(z, "[<-"(names(z), 3, "c2")).
That is ok. Also effective would be:

z <- matrix( c(x,y), ncol=length(x) )
Not sure why you are trying to do that to x since it is a vector but  
it can be done if you make it a matrix first. Take a look at these and  
see if you can figure out what is happening:

 > x <- matrix(x,2,3)  # second and third arguments of matrix function  
are nrow and ncol.
 > x
      [,1] [,2] [,3]
[1,]    1    3    2
[2,]    2    1    3

And then try:
 > x = c(1,2,3)
 > x <- matrix(x,2,3,byrow=TRUE)
 > x
      [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    3

And now that x is a matrix, this will work:

 > x[2,] <- y
 > x
      [,1] [,2] [,3]
[1,]    1    2    3
[2,]    3    4    5

-- David Winsemius
#
On Feb 25, 2009, at 12:12 AM, David Winsemius wrote:

            
Would need byrow=TRUE for that to behave as desired.
 > z <- matrix(c(x,y), 2.3, byrow=TRUE)
 > z
      [,1] [,2] [,3]
[1,]    1    2    3
[2,]    3    4    5
#
Fuchs Ira wrote:
because a[2] becomes a newly allocated vector once you make the
assignment, and so the assignment does not affect a.  however:

    names(a)[2] = 'too'
   
will affect a the way you seem to wish.
you can do this:

    z = matrix(c(x, y), nrow=2, ncol=3, byrow=TRUE)

but rbind seems much simpler.

vQ
#
David Winsemius wrote:
the following:

    names(a[2]) = 'foo'

has (partially) a functional flavour, in that you assign to the names of
a *copy* of a part of a, while

    names(a)[2] = 'foo'

does not have the flavour, in that you assign to the names of a;  it
seems, according to the man page you quote, to be equivalent to:

    a = 'names<-'(a, '[<-.'(names(a), 2, 'foo'))

which proceeds as follows:

    tmp1 = names(a)
    # get a copy of the names of a, no effect on a

    tmp2 = '[<-'(tmp1, 2, 'foo')
    # get a copy of tmp1 with the second element replaced with 'foo'
    # no effect on either a or tmp1

    tmp3 = 'names<-'(a, tmp2)
    # get a copy of a with its names replaced with tmp2
    # no effect on either a, tmp1, or tmp2

    a = tmp3
    # backassign the result to a

vQ
#
a quick follow-up:

    e = new.env()
    e$a = 1
    names(e)
    # NULL
    names(e) = 'a'
    # error in names(e) = "foo" : names() applied to a non-vector

this is surprising.  names(e) 'works', there is no complaint, but when
names<- is used, the error is about the use of names, not names<-.

btw. ?names says:

"Description:

     Functions to get or set the names of an object.

Usage:

     names(x)
     names(x) <- value

Arguments:

       x: an R object.
"

and there is no clarification in the rest of the page that x cannot be
an environment, or that it has to be a vector.  furthermore:

    p = pairlist(a=1)
    names(p)
    # "a"
    names(p) = 'b'
    # fine
    is.vector(p)
    # FALSE

which is incoherent with the above error message, in that p is *not* a
vector.

vQ
Wacek Kusnierczyk wrote: