0

I've been trying take two data.tables, cbind them, and re-sort the columns so the first column of the first data.table is the next to the first column of the first data.table and so on.

I used the Map function to come up with the interlocking indexes but when I pass the values to j, it just returns the indexes as a vector. Here are some examples of what I'm talking about:

m <- data.table(a = 1:10, b = letters[1:10], c = LETTERS[1:10], d = rnorm(10))
m[, c(1, 3, 2, 4)] # works
m[, unlist(list(1, 3, 2, 4))] # doesn't work
m[, c(unlist(list(1, 3, 2, 4)))] # works
m[, c(unlist(Map(c, c(1, 2), c(3, 4))))] # doesn't work
James B
  • 474
  • 2
  • 10

2 Answers2

0

data.table operates a bit differently than data.frame. You can achieve what you want with the Map() function as follows:

m <- data.table(a = 1:10, b = letters[1:10], c = LETTERS[1:10], d = rnorm(10))
column_order = unlist(Map(c, c(1, 2), c(3, 4)))

setcolorder(m,column_order)
lunar_props
  • 118
  • 3
0

Using @Arun's answer, you can interleave any number of sequences:

d1 <- data.table(a = 1:10, b = letters[1:10])
d2 <- data.table(c = LETTERS[1:10], d = rnorm(10))

make_m <- function(...){
  ds = list(...)
  co = order(sequence(lengths(ds)))

  out = do.call(cbind, ds)
  setcolorder(out, co)[]
}

make_m(d1, d2)

     a c b            d
 1:  1 A a  0.260136119
 2:  2 B b  0.183627443
 3:  3 C c -0.597449642
 4:  4 D d -0.376898147
 5:  5 E e  0.857690453
 6:  6 F f  0.419492431
 7:  7 G g  1.491188939
 8:  8 H h -0.871813368
 9:  9 I i -0.086545214
10: 10 J j  0.002349929

The code is a little different because lengths was not available when Arun's answer was written.

Frank 2
  • 581
  • 2
  • 8