Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rbind() returning an odd result

Tags:

r

This has all the signs of being something that's so trivially stupid that I'll regret asking it in a public forum, but I've now stumped a few people on it so c'est la vie.

I'm running the following block of code, and not getting the result that I expect:

zz <- list(a=list('a', 'b', 'c', 'd'), b=list('f', 'g', '2', '1'),
           c=list('t', 'w', 'x', '6'))
padMat <- do.call('cbind', zz)
headMat <- matrix(c(colnames(padMat), rep('foo', ncol(padMat))), nrow=2, byrow=TRUE)
rbind(headMat, padMat)

I had expected:

a    b    c
foo  foo  foo
a    f    t
b    g    w
c    2    x
d    1    6

Instead I'm getting:

a    b    c
a    f    t 
b    g    w
c    2    x
d    1    6
NULL NULL NULL

It appears that it's filling in the upper part of the rbind by row, and then adding a row of NULL values at the end.

A couple of notes:

  • This works AOK as long as headMat is a single row

  • To double check, I also got rid of the dimnames for padMat, this wasn't affecting things

  • Another thought was that it somehow had to do with the byrow=TRUE, but the same behavior happens if you take that out

like image 867
geoffjentry Avatar asked Jun 20 '11 19:06

geoffjentry


2 Answers

padMat is a list (with a dim attribute), not what you usually think of as a matrix.

> padMat <- do.call('cbind', zz)
> str(padMat)
List of 12
 $ : chr "a"
 $ : chr "b"
 $ : chr "c"
 $ : chr "d"
 $ : chr "f"
 $ : chr "g"
 $ : chr "2"
 $ : chr "1"
 $ : chr "t"
 $ : chr "w"
 $ : chr "x"
 $ : chr "6"
 - attr(*, "dim")= int [1:2] 4 3
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:3] "a" "b" "c"

I suspect you want something like:

> padMat <- do.call(cbind,lapply(zz,c,recursive=TRUE))
> str(padMat)
 chr [1:4, 1:3] "a" "b" "c" "d" "f" "g" "2" "1" "t" "w" ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:3] "a" "b" "c"

The lesson here is, "str is your friend." :)

like image 199
Joshua Ulrich Avatar answered Oct 21 '22 14:10

Joshua Ulrich


The problem appears to stem from the fact that padMat is a strange matrix. R reports that is a list of 12 with dimensions:

R> str(padMat)
List of 12
 $ : chr "a"
 $ : chr "b"
 $ : chr "c"
 $ : chr "d"
 $ : chr "f"
 $ : chr "g"
 $ : chr "2"
 $ : chr "1"
 $ : chr "t"
 $ : chr "w"
 $ : chr "x"
 $ : chr "6"
 - attr(*, "dim")= int [1:2] 4 3
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:3] "a" "b" "c"

That appears to be the source of the problem, as recasting as a matrix works:

R> rbind(headMat, matrix(unlist(padMat), ncol = 3))
     [,1]  [,2]  [,3] 
[1,] "a"   "b"   "c"  
[2,] "foo" "foo" "foo"
[3,] "a"   "f"   "t"  
[4,] "b"   "g"   "w"  
[5,] "c"   "2"   "x"  
[6,] "d"   "1"   "6"
like image 23
Gavin Simpson Avatar answered Oct 21 '22 15:10

Gavin Simpson