Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining (cbind) vectors of different length

Tags:

merge

list

r

matrix

I have several vectors of unequal length and I would like to cbind them. I've put the vectors into a list and I have tried to combine the using 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) 

As expected, the number of rows in the resulting matrix is the length of the longest vector, and the values of the shorter vectors are recycled to make up for the length.

Instead I'd like to pad the shorter vectors with NA values to obtain the same length as the longest vector. I'd like the matrix to look like this:

#      [,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 

How can I go about doing this?

like image 477
Nick Avatar asked Apr 03 '11 18:04

Nick


People also ask

How do you combine vectors into data frames?

Method 1: Using cbind() cbind() function stands for column-bind. This function can be used to combine several vectors, matrices, or DataFrames by columns. In this approach, a single vector is considered as one column and then these columns are combined to form a dataframe.

What is the difference between Rbind and Cbind?

cbind() and rbind() both create matrices by combining several vectors of the same length. cbind() combines vectors as columns, while rbind() combines them as rows. Let's use these functions to create a matrix with the numbers 1 through 30.

What is the use of Cbind () function?

The cbind function is used to combine vectors, matrices and/or data frames by columns.


2 Answers

You can use indexing, if you index a number beyond the size of the object it returns NA. This works for any arbitrary number of rows defined with foo:

nm <- list(1:8,3:8,1:5)  foo <- 8  sapply(nm, '[', 1:foo) 

EDIT:

Or in one line using the largest vector as number of rows:

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

From R 3.2.0 you may use lengths ("get the length of each element of a list") instead of sapply(nm, length):

sapply(nm, '[', seq(max(lengths(nm)))) 
like image 137
Sacha Epskamp Avatar answered Sep 21 '22 13:09

Sacha Epskamp


You should fill vectors with NA before calling do.call.

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) 
like image 30
Wojciech Sobala Avatar answered Sep 23 '22 13:09

Wojciech Sobala