1

I am looking for options (preferably using base R) for binding different length data frames starting from bottom. The remaining/missing rows should be NAd out. Example:

set.seed(1212)
a = as.data.frame(rnorm(1, 0, 1))
b = as.data.frame(rnorm(4, 0, 1))
c = as.data.frame(rnorm(3, 0, 1))

Expected output:

  rnorm(1, 0, 1) rnorm(4, 0, 1) rnorm(3, 0, 1)
1 NA               1.8374224       NA
2 NA               0.3436815       0.03719874
3 NA              -1.3600955      -1.92311898
4 -0.6290858       0.5358145       0.41087971
AK88
  • 2,946
  • 2
  • 12
  • 31
  • 1
    Use `rowr::cbind.fill(a, b,c)` – akrun Aug 11 '17 at 11:18
  • thanks @akrun. is there any way to do this using just base R? `cbind()` or `merge()`? – AK88 Aug 11 '17 at 11:19
  • 1
    It won't be a one-liner in base R, or will be pretty complicated one-liner. Quite a few similar questions have been asked, so you can surely find base R answers. – lmo Aug 11 '17 at 11:22
  • 1
    @lmo, got it. loki's answer seems good enough. will try that out. – AK88 Aug 11 '17 at 11:23

3 Answers3

2

First, assess the maximum length of the columns to bind.

lenMax <- max(length(a[,1]), length(b[,1]), length(c[,1]))

Then, use this length to fill columns of a new data.frame with NAs so they fit.

data.frame(a = c(rep(NA, lenMax - length(a[,1])), a[,1]), 
           b = c(rep(NA, lenMax - length(b[,1])), b[,1]), 
           c = c(rep(NA, lenMax - length(c[,1])), c[,1]))

#            a          b           c
# 1         NA  1.8374224          NA
# 2         NA  0.3436815  0.03719874
# 3         NA -1.3600955 -1.92311898
# 4 -0.6290858  0.5358145  0.41087971
loki
  • 9,816
  • 7
  • 56
  • 82
2

You can use smartbind()

gtools::smartbind(a,b,c)
#    rnorm(1, 0, 1) rnorm(4, 0, 1) rnorm(3, 0, 1)
#1       -0.6290858             NA             NA
#2:1             NA      1.8374224             NA
#2:2             NA      0.3436815             NA
#2:3             NA     -1.3600955             NA
#2:4             NA      0.5358145             NA
#3:1             NA             NA     0.03719874
#3:2             NA             NA    -1.92311898
#3:3             NA             NA     0.41087971
mtoto
  • 23,919
  • 4
  • 58
  • 71
1

We can use rowr

library(rowr)
 apply(rowr::cbind.fill(a, b, c, fill = NA), 2, function(x) x[order(!is.na(x))])
#    rnorm.1..0..1. rnorm.4..0..1. rnorm.3..0..1.
#[1,]             NA      1.8374224             NA
#[2,]             NA      0.3436815     0.03719874
#[3,]             NA     -1.3600955    -1.92311898
#[4,]     -0.6290858      0.5358145     0.41087971
akrun
  • 874,273
  • 37
  • 540
  • 662