2

Suppose there are two dataframes as follows with same column names and I want to combine/concatenate one after the other without merging the common columns. There is a way of assigning it columnwise like df1[3]<-df2[1] but would like to know if there's some other way.

df1<-data.frame(A=c(1:10), B=c(2:5, rep(NA,6)))
df2<-data.frame(A=c(12:20), B=c(32:40))

Expected Output:

A  B  A.1 B.1
1  2  12  32
2  3  13  33
3  4  14  34
4  5  15  35
5  NA 16  36
6  NA 17  37
7  NA 18  38
8  NA 19  39
9  NA 20  40
10 NA NA  NA
Aaryan
  • 31
  • 4

4 Answers4

1

I tend to work with multiple frames like this as a list of frames. Try this:

LOF <- list(df1, df2)
maxrows <- max(sapply(LOF, nrow))
out <- do.call(cbind, lapply(LOF, function(z) z[seq_len(maxrows),]))
names(out) <- make.names(names(out), unique = TRUE)
out
#     A  B A.1 B.1
# 1   1  2  12  32
# 2   2  3  13  33
# 3   3  4  14  34
# 4   4  5  15  35
# 5   5 NA  16  36
# 6   6 NA  17  37
# 7   7 NA  18  38
# 8   8 NA  19  39
# 9   9 NA  20  40
# 10 10 NA  NA  NA

One advantage of this is that it allows you to work with an arbitrary number of frames, not just two.

r2evans
  • 141,215
  • 6
  • 77
  • 149
1

One base R way could be

setNames(Reduce(cbind.data.frame, 
                Map(`length<-`, c(df1, df2), max(nrow(df1), nrow(df2)))),
         paste0(names(df1), rep(c('', '.1'), each=2)))
#     A  B A.1 B.1
# 1   1  2  12  32
# 2   2  3  13  33
# 3   3  4  14  34
# 4   4  5  15  35
# 5   5 NA  16  36
# 6   6 NA  17  37
# 7   7 NA  18  38
# 8   8 NA  19  39
# 9   9 NA  20  40
# 10 10 NA  NA  NA
jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • FYI, you don't need `Map`, this works equally well with `lapply(c(df1, df2), \`length<-\`, max(nrow(df1), nrow(df2)))` – r2evans Jul 06 '21 at 18:36
1

Another option is to use the merge function. The documentation can be a bit cryptic, so here is a short explanation of the arguments:

  • by -- "the name "row.names" or the number 0 specifies the row names"
  • all = TRUE -- keeps all original rows from both dataframes
  • suffixes -- specify how you want the duplicated colnames to be distinguished
  • sort -- keep original sorting
merge(df1, df2, by = 0, all = TRUE, suffixes = c('', '.1'), sort = FALSE)
nniloc
  • 4,128
  • 2
  • 11
  • 22
0

One way would be

cbind(
   df1,
   rbind(
      df2,
      rep(NA, nrow(df1) - nrow(df2))
   )
)
`````
Daniel
  • 1,005
  • 1
  • 16
  • 22