rbind()返回一个奇怪的结果

时间:2011-06-20 19:11:20

标签: r

这有一些显而易见的迹象,我会后悔在一个公共论坛上提出这个问题,但我现在已经把一些人难倒了,所以我很难过。

我正在运行以下代码块,但没有得到我期望的结果:

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)

我曾预料到:

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

相反,我得到了:

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

它似乎是按行填充rbind的上半部分,然后在末尾添加一行NULL值。

几点说明:

  • 只要headMat是单行

  • ,这就可以使用AOK
  • 要仔细检查,我也摆脱了padMat的dimnames,这不会影响事情

  • 另一个想法是它以某种方式与 byrow = TRUE 有关,但是如果你把它拿出来就会发生同样的行为

3 个答案:

答案 0 :(得分:9)

padMat是一个列表(带有dim属性),而不是您通常认为的矩阵。

> 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"

我怀疑你想要这样的东西:

> 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"

这里的教训是,“str是你的朋友。” :)

答案 1 :(得分:8)

问题似乎源于padMat是一个奇怪的矩阵。 R报告是12个维度列表:

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"

这似乎是问题的根源,因为重建为矩阵有效:

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"

答案 2 :(得分:5)

其他人已经正确地指出了padMat具有模式list的事实,如果你查看rbind和cbind的文档,那就很糟糕了:

In the default method, all the vectors/matrices must be atomic (see vector) or lists.

这就是do.call有效的原因,因为zz的元素本身就是列表。如果您将zz的定义更改为以下内容:

zz <- list(a=c('a', 'b', 'c', 'd'), b=c('f', 'g', '2', '1'),
       c=c('t', 'w', 'x', '6'))

代码按预期工作。

我认为,从rbind和cbind的文档中可以获得更多的洞察力:

The type of a matrix result determined from the highest type of any of the inputs 
 in the hierarchy raw < logical < integer < real < complex < character < list .