2011-04-03 93 views
21

我有幾個向量長度不等,我想cbind他們。我已經把載體放入一個列表,我試圖結合使用do.call(cbind, ...)不同長度的組合(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 

我該如何去做這件事?

+1

閃光的光輝:nm < - cbind(z1, c(z2,rep(NA,length(z1)-length(z2))) ) – Nick 2011-04-03 18:17:40

回答

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) 
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))) 
}) 
+2

您總是最好使用'vapply'而不是'sapply'因爲這將保證您獲得您期望的輸出類型。 – hadley 2011-04-04 12:09:34

+0

@hadley你能否詳細說明你的評論?我不明白vapply和sapply之間轉移到這個問題的區別。 – guerda 2015-02-18 14:23:45

+1

sapply危險程序,因爲它不是類型穩定的 - 取決於nm的長度,你會得到不同的類型 – hadley 2015-02-19 16:22:41

21

您可以使用索引,如果您索引超出對象大小的數字,則返回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)))) 
+2

'['的意思是什麼? – user702846 2011-12-01 10:05:52

+0

''[''是你在索引中使用的操作符'['foo [1:10]''的名稱)。另見'?'['' – 2011-12-01 10:09:16

+0

如果第一列比另外兩列短,則單線解決方案失敗。 – bshor 2012-07-17 19:35:17