3
votes

Is this a bug in R or does it make sense?

## works
aa <- matrix(nrow=1,ncol=2)
dimnames(aa)[[2]] <- c("a","b")
dimnames(aa)[[1]] <- c("c")

## does not work
bb <- matrix(nrow=1,ncol=2)
dimnames(bb)[[1]] <- c("c")
Error in dimnames(bb)[[1]] <- c("c") : 'dimnames' must be a list

Thanks for explanations !

3

3 Answers

9
votes

This is expected behavior. When you assign to an index of an element of an object, R will create the element if it doesn't exist. In your example "dimnames" doesn't exist in aa, so R tries to create "dimnames" based on what you're assigning to it. Consider assigning elements named "a", "b", and "c" of a list:

> L <- list()
> L$a[[1]] <- 5
> L$b[[3]] <- "foo"
> L$c[[4]] <- c(1,2,3)
> class(L$a)
[1] "numeric"
> class(L$b)
[1] "character"
> class(L$c)
[1] "list"

Now the problem with saying L$a[[1]] <- anything is that L$a doesn't exist yet. What happens when an element doesn't exist is that R just creates the simplest type of element that would work. As you can see, L$a[[1]] <- 5 would make sense if L$a is a numeric vector, so R makes it a numeric vector. L$b[[3]] <- "foo" doesn't make sense if L$b is a numeric vector, but it would make sense if L$b is a character vector, so that's what R creates. But L$c[[4]] <- c(1,2,3) can only happen if L$c is a list, so in that case you get a list.

In your case, it tries to create dimnames according to that rule; so it makes dimnames(aa) a list, but it only makes dimnames(bb) a character vector. But dimnames has an extra constraint that it has to be a list, so it objects and you get an error.

1
votes

You could use

dimnames(bb)[[1]] <- list("c")

This command will assign the name as a row name.

I suppose the error is due to the list of dimnames not being created. Otherwise if you access the second part of the list first ([[2]]), the list will be created. Therefore, you can also access dimnames[[1]] afterwards.

0
votes

I would do what the error says:

dimnames(bb)[[1]] <- list("c")
> bb
  [,1] [,2]
c   NA   NA

What also works:

dimnames(bb)[[1]] <- "c"