Search code examples
rbind

How to column bind 2 tables but remove the same column


i want to join 2 Table with same column but only 1 different column and display the same column to one single column.

if:

dt1 <- have the column names (a,b,c,d,e)

a b c d e

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

dt2 <- have the column names (a,b,c,d,f)

a b c d f

1 2 3 4 6

1 2 3 4 6

1 2 3 4 6

dt3 <- cbind(dt1, dt2)

I just want to do some simple table combining with R using cbind

This yield:

dt3 <- have the column names(a,b,c,d,e,a,b,c,d,f)

a b c d e a b c d f

1 2 3 4 5 1 2 3 4 6

1 2 3 4 5 1 2 3 4 6

1 2 3 4 5 1 2 3 4 6

i want the output to be:

dt3 <- have the column names (a,b,c,d,e,f)

a b c d e f

1 2 3 4 5 6

1 2 3 4 5 6

1 2 3 4 5 6


Solution

  • We can use setdiff to get the columns in one that is not found in another

    nm1 <- setdiff(names(dt2), names(dt1))
    out <- cbind(dt1, dt2[nm1])
    

    If we have multiple datasets, place it in a list get the intersecting column names (names that are common in all), get the setdiff of those from the column names of each individual datasets in the list and cbind

    lst1 <- list(dt1, dt2, dt3)
    nm2 <- Reduce(intersect, lapply(lst1, names))
    cbind(lst1[[1]], do.call(cbind,
        lapply(lst1[-1], function(dat) dat[setdiff(names(dat), nm2)] )))
    #    a  b  c  d  e  f  g
    #1   1 11 21 31 41 51 61
    #2   2 12 22 32 42 52 62
    #3   3 13 23 33 43 53 63
    #4   4 14 24 34 44 54 64
    #5   5 15 25 35 45 55 65
    #6   6 16 26 36 46 56 66
    #7   7 17 27 37 47 57 67
    #8   8 18 28 38 48 58 68
    #9   9 19 29 39 49 59 69
    #10 10 20 30 40 50 60 70
    

    Or using a for loop

    out1 <- dt1 # initialize with the first data
    for(i in 2:length(lst1)) {
    
        out1 <- cbind(out1, lst1[[i]][setdiff(names(lst1[[i]]), nm2)])
    }
    out1
    

    data

    dt1 <- as.data.frame(matrix(1:50, 10, 5, dimnames = list(NULL, letters[1:5])))
    dt2 <- as.data.frame(matrix(11:60, 10, 5, dimnames = list(NULL, letters[c(1:4, 6)])))
    dt3 <-  as.data.frame(matrix(21:70, 10, 5, 
         dimnames = list(NULL, letters[c(1:4, 7)])))