合并不同长度的矩阵并保留列名

时间:2019-04-25 09:01:00

标签: r cbind stringi

关于合并具有不同长度的向量here,存在类似的问题,但是所有答案(@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 个答案:

答案 0 :(得分:2)

由于可以使用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 :(得分:1)

这是一个稍微简洁的基本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,然后添加rowmerge,并加上rowmerge按行设置by = 0(感谢@Henrik)。请注意,这将返回data.frame而不是matrix

答案 2 :(得分:0)

这里使用的是基数:

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