Объединяйте матрицы разной длины и сохраняйте имена столбцов - PullRequest
1 голос
/ 25 апреля 2019

Существует аналогичный вопрос о комбинировании векторов различной длины здесь , но все ответы (кроме ответа @ Ronak Shah ) теряют имена / имена.

Моя проблема в том, что мне нужно сохранить имена столбцов, что возможно при использовании пакета rowr и cbind.fills.

Я хотел бы остаться в base-R или использовать stringi, и выходной сигнал должен оставаться матрицей.

Данные испытаний:

inp <- list(structure(c("1", "2"), .Dim = 2:1, .Dimnames = list(NULL,"D1")), 
            structure(c("3", "4", "5"), .Dim = c(3L, 1L), .Dimnames = list(NULL, "D2")))

Я знаю, что могу заранее получить имена столбцов, а затем переназначить их после создания матрицы, например:

## Using stringi
colnam <- unlist(lapply(inp, colnames))
out <- stri_list2matrix(inp)
colnames(out) <- colnam
out    

## Using base-R
colnam <- unlist(lapply(inp, colnames))
max_length <- max(lengths(inp))
nm_filled <- lapply(inp, function(x) {
  ans <- rep(NA, length = max_length)
  ans[1:length(x)]<- x
  ans
})
out <- do.call(cbind, nm_filled)
colnames(out) <- colnam
out

Есть ли другие опции, которые сохраняют имена столбцов?

Ответы [ 3 ]

2 голосов
/ 25 апреля 2019

Поскольку вы можете использовать stringi, вы можете использовать функцию stri_list2matrix(), т.е.

setNames(as.data.frame(stringi::stri_list2matrix(inp)), sapply(inp, colnames))
#    D1 D2
#1    1  3
#2    2  4
#3 <NA>  5
1 голос
/ 25 апреля 2019

Вот несколько более краткая базовая вариация R

len <- max(lengths(inp))
nms <- sapply(inp, colnames)
do.call(cbind, setNames(lapply(inp, function(x)
    replace(rep(NA, len), 1:length(x), x)), nms))
#      D1  D2
#[1,] "1" "3"
#[2,] "2" "4"
#[3,] NA  "5"

Не уверен, что это достаточно отличное решение от того, что вы уже опубликовали. Удалит, если сочтет слишком похожим.


Обновление

Или как насчет merge?

Reduce(
    function(x, y) merge(x, y, all = T, by = 0),
    lapply(inp, as.data.frame))[, -1]
#    D1 D2
#1    1  3
#2    2  4
#3 <NA>  5

Идея заключается в том, чтобы преобразовать записи list в data.frame s, , затем добавить row число и merge на row и merge по строке, установив by = 0 (спасибо @Henrik). Обратите внимание, что это вернет data.frame, а не matrix.

0 голосов
/ 25 апреля 2019

Здесь используется base:

do.call(cbind,
        lapply(inp, function(i){
          x <- data.frame(i, stringsAsFactors = FALSE)
          as.matrix( x[ seq(max(lengths(inp))), , drop = FALSE ] ) 
          #if we matrices have more than 1 column use:
          #as.matrix( x[ seq(max(sapply(inp, nrow))), , drop = FALSE ] )
        }
        ))


#    D1  D2 
# 1  "1" "3"
# 2  "2" "4"
# NA NA  "5"

Идея состоит в том, чтобы все матрицы имели одинаковое количество строк.Когда мы подставляем индекс dataframe , несуществующие строки будут возвращены как NA, тогда мы конвертируем обратно в матрицу и cbind .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...