组合(cbind)不同长度的向量
Posted
技术标签:
【中文标题】组合(cbind)不同长度的向量【英文标题】:Combining (cbind) vectors of different length 【发布时间】:2011-07-28 17:41:50 【问题描述】:我有几个长度不等的向量,我想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
我该怎么做?
【问题讨论】:
一闪而过:nm 【参考方案1】:你应该在调用 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】:这是 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)))
)
【讨论】:
你总是最好使用vapply
而不是sapply
,因为这样可以保证你得到你期望的输出类型。
@hadley 你能详细说明你的评论吗?我不明白 vapply 和 sapply 转移到这个问题的区别。
sapply 编程很危险,因为它类型不稳定 - 取决于 nm
的长度,您会得到不同的类型【参考方案3】:
您可以使用索引,如果您索引的数字超出了它返回的对象大小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))))
【讨论】:
'['
是您在索引中使用的运算符 [
的名称 (foo[1:10]
)。另见?'['
如果第一列比其他两列短,则单行解决方案失败。
保留列名的唯一答案来自@Ronak Shah,使用rowr
包。是否有保留列名的基本 R 替代方案?【参考方案4】:
聚会迟到了,但您可以使用来自rowr
包的cbind.fill
和fill = 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
如果您有一个名为 list
并且想要维护标题,您可以使用 setNames
nm <- list(a = 1:8, b = 3:8, c = 1:5)
setNames(do.call(cbind.fill, c(nm, fill = NA)), names(nm))
# a b c
#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】:这是一个使用来自stringi
的stri_list2matrix
的选项
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
【讨论】:
以上是关于组合(cbind)不同长度的向量的主要内容,如果未能解决你的问题,请参考以下文章