Take the 2-minute tour ×

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 !

share|improve this question
add comment

3 Answers

up vote 7 down vote accepted

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.

share|improve this answer
Thanks! that was helpful ! –  Florian Sep 25 '12 at 10:49
+1 Well illustrated. –  Marc in the box Sep 25 '12 at 12:56
add comment

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.

share|improve this answer
I'm actually surprised that works; aa$b[[1]] <- list("c") makes aa$b a list containing a list, which isn't what you want with dimnames. Using the single brackets i.e. dimnames(aa)[1] <- list("c") also works and is more consistent with how R behaves elsewhere. –  crowding Sep 25 '12 at 8:46
@crowding I agree, that it's more consistent to use single brackets. But actually, the results of dimnames(aa)[1] <- list("c")and dimnames(aa)[[1]] <- list("c") are identical. –  Sven Hohenstein Sep 25 '12 at 8:56
add comment

I would do what the error says:

> bb
  [,1] [,2]
c   NA   NA

What also works:

dimnames(bb)[[1]] <- "c"
share|improve this answer
add comment

Your Answer


