rbind () возвращает нечетный результат - PullRequest
8 голосов
/ 20 июня 2011

У этого есть все признаки того, что это настолько банально глупо, что я пожалею, что спросил об этом на публичном форуме, но теперь я поставил несколько человек в тупик, так что c'est la vie.

Я запускаю следующий блок кода и не получаю ожидаемого результата:

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-значениями.

Пара примечаний:

  • Это работает AOK, пока headMat представляет собой одну строку

  • Для двойной проверки,Я также избавился от dimnames для padMat, это не повлияло на вещи

  • Другая мысль была о том, что это как-то связано с byrow = TRUE , ното же самое происходит, если вы уберете это

Ответы [ 3 ]

9 голосов
/ 20 июня 2011

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 твой друг».:)

8 голосов
/ 20 июня 2011

Проблема, похоже, связана с тем, что 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"
5 голосов
/ 20 июня 2011

Другие правильно указали на тот факт, что 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 .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...