異なる長さのベクターがいくつかあり、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
どうすればこれを行うことができますか?
インデックスを使用できます。オブジェクトのサイズを超える数値をインデックス化すると、NA
が返されます。これは、foo
で定義された任意の行数で機能します。
_nm <- list(1:8,3:8,1:5)
foo <- 8
sapply(nm, '[', 1:foo)
_
編集:
または、最大ベクトルを行数として使用する1行で:
_sapply(nm, '[', seq(max(sapply(nm,length))))
_
_R 3.2.0
_から、sapply(nm, length)
の代わりにlengths
(「リストの各要素の長さを取得」)を使用できます。
_sapply(nm, '[', seq(max(lengths(nm))))
_
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)
これは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)))
})
パーティーに遅れましたが、cbind.fill
from rowr
パッケージの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
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