How to cbind or rbind different lengths vectors without repeating the elements of the shorter vectors?

Viewed 110558
cbind(1:2, 1:10)  
     [,1] [,2]  
  [1,]    1    1  
  [2,]    2    2  
  [3,]    1    3  
  [4,]    2    4  
  [5,]    1    5  
  [6,]    2    6  
  [7,]    1    7  
  [8,]    2    8  
  [9,]    1    9  
 [10,]    2   10  

I want an output like below

[,1] [,2]  
[1,] 1 1  
[2,] 2 2  
[3,]   3  
[4,]   4  
[5,]   5  
[6,]   6  
[7,]   7  
[8,]   8  
[9,]   9  
[10,]  10  
6 Answers

I would like to propose an alternate solution that makes use of the rowr package and their cbind.fill function.

> rowr::cbind.fill(1:2,1:10, fill = NA);

   object object
1       1      1
2       2      2
3      NA      3
4      NA      4
5      NA      5
6      NA      6
7      NA      7
8      NA      8
9      NA      9
10     NA     10

Or alternatively, to match the OP's desired output:

> rowr::cbind.fill(1:2,1:10, fill = '');

   object object
1       1      1
2       2      2
3              3
4              4
5              5
6              6
7              7
8              8
9              9
10            10

Given that some of the solutions above rely on packages that are no longer available, here a helper function that only uses dplyr.

bind_cols_fill <- function(df_list) {

  max_rows <- map_int(df_list, nrow) %>% max()
  
  map(df_list, function(df) {
    if(nrow(df) == max_rows) return(df)
    first <- names(df)[1] %>% sym()
    df %>% add_row(!!first := rep(NA, max_rows - nrow(df)))
  }) %>% bind_cols()
}

Note that this takes a list of data frames, so that it is slightly cumbersome if one only wants to combine two vectors:

x <- 1:2
y <- 1:10
bind_cols_fill(list(tibble(x), tibble(y)) 

Another solution with no dependencies:

my_bind <- function(x, y){
if(length(x = x) > length(x = y)){
    len_diff <- length(x) - length(y)
    y <- c(y, rep(NA, len_diff))
}else if(length(x = x) < length(x = y)){
    len_diff <- length(y) - length(x)
    x <- c(x, rep(NA, len_diff))
}
cbind(x, y)
}
my_bind(x = letters[1:4], y = letters[1:2])
Related