组合不同长度的(cbind)向量

时间:2011-04-03 18:12:16

标签: list r merge matrix

我有几个长度不等的向量,我想cbind他们。我已将这些向量放入列表中,并尝试将使用do.call(cbind, ...)

组合在一起
nm <- list(1:8, 3:8, 1:5)
do.call(cbind, nm)

#      [,1] [,2] [,3]
# [1,]    1    3    1
# [2,]    2    4    2
# [3,]    3    5    3
# [4,]    4    6    4
# [5,]    5    7    5
# [6,]    6    8    1
# [7,]    7    3    2
# [8,]    8    4    3
# Warning message:
#   In (function (..., deparse.level = 1)  :
#         number of rows of result is not a multiple of vector length (arg 2)

正如预期的那样,结果矩阵中的行数是最长向量的长度,并且较短向量的值将被回收以弥补长度。

相反,我想用NA值填充较短的向量,以获得与最长向量相同的长度。我希望矩阵看起来像这样:

#      [,1] [,2] [,3]
# [1,]    1    3    1
# [2,]    2    4    2
# [3,]    3    5    3
# [4,]    4    6    4
# [5,]    5    7    5
# [6,]    6    8    NA
# [7,]    7    NA   NA
# [8,]    8    NA   NA

我该怎么做呢?

5 个答案:

答案 0 :(得分:28)

如果索引的数字超出其返回的对象大小NA,则可以使用索引。这适用于使用foo

定义的任意数量的行
nm <- list(1:8,3:8,1:5)

foo <- 8

sapply(nm, '[', 1:foo)

编辑:

或者使用最大向量作为行数的一行:

sapply(nm, '[', seq(max(sapply(nm,length))))

R 3.2.0开始,您可以使用lengths(“获取列表中每个元素的长度”)而不是sapply(nm, length)

sapply(nm, '[', seq(max(lengths(nm))))

答案 1 :(得分:5)

在调用do.call之前,你应该用NA填充向量。

nm <- list(1:8,3:8,1:5)

max_length <- max(unlist(lapply(nm,length)))
nm_filled <- lapply(nm,function(x) {ans <- rep(NA,length=max_length);
                                    ans[1:length(x)]<- x;
                                    return(ans)})
do.call(cbind,nm_filled)

答案 2 :(得分:3)

这是Wojciech解决方案的缩短版本。

nm <- list(1:8,3:8,1:5)
max_length <- max(sapply(nm,length))
sapply(nm, function(x){
    c(x, rep(NA, max_length - length(x)))
})

答案 3 :(得分:1)

这是使用stri_list2matrix中的stringi的选项

library(stringi)
out <- stri_list2matrix(nm)
class(out) <- 'numeric'
out
#      [,1] [,2] [,3]
#[1,]    1    3    1
#[2,]    2    4    2
#[3,]    3    5    3
#[4,]    4    6    4
#[5,]    5    7    5
#[6,]    6    8   NA
#[7,]    7   NA   NA
#[8,]    8   NA   NA

答案 4 :(得分:0)

迟到聚会,但您可以将cbind.fill包中的rowrfill = NA一起使用

library(rowr)
do.call(cbind.fill, c(nm, fill = NA))

#  object object object
#1      1      3      1
#2      2      4      2
#3      3      5      3
#4      4      6      4
#5      5      7      5
#6      6      8     NA
#7      7     NA     NA
#8      8     NA     NA