Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better way to turn two columns into one in R/Splus?

Tags:

r

matrix

Currently I do the following:

x <- cbind(c(1, 2, 3), c(4, 5, 6))
x.merged <- matrix(t(x), ncol=1)

to create one column with values 1, 4, 2, 5, 3, 6, from the matrix x. But relying on t(x) seems a bit clunky. Is there a better way to do this? I'd like to avoid a for-loop or apply if there's a simpler built-in function that handles this sort of thing.

EDIT: To be clearer, x is just given to me. The first line of code above was only meant to illustrate the values involved. It might have been better for me to write:

> x
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
like image 432
lowndrul Avatar asked Nov 28 '25 09:11

lowndrul


2 Answers

Actually, if you make it a vector it doesn't take more than :

> c(t(x))
[1] 1 4 2 5 3 6

Or, if you really have to avoid t() then you could do :

> c(apply(x,2,rbind))
[1] 1 4 2 5 3 6

This works for an arbitrary number of columns, but includes an apply. If you don't want to use that one, you'll have to manually specify all the columns you want to paste behind eachother. But the t() solution is by far the fastest :

> n <- 10000000    
> x <- matrix(rnorm(n),ncol=2)
> system.time(c(t(x)))
   user  system elapsed 
   0.07    0.00    0.06 

> system.time(c(rbind(x[,1],x[,2])))
   user  system elapsed 
   0.22    0.05    0.26 

Remember that a matrix can be seen as a vector with dimensions added to it, and is always read columnwise. So you cannot really avoid the t() in your solution. You could always just use it as a vector, eg :

> x[4]
[1] 4

just works, as long as you remember that the matrix is read columnwise. So in your case you'll need

> t(x)[4]
[1] 5

In case you really need it as a matrix, then :

> matrix(t(x))
     [,1]
[1,]    1
[2,]    4
[3,]    2
[4,]    5
[5,]    3
[6,]    6
like image 108
Joris Meys Avatar answered Nov 29 '25 23:11

Joris Meys


I think the way to do this with the fewest keystrokes is:

c(rbind(c(1, 2, 3), c(4, 5, 6)))

Using rbind eliminates the transpose, and c is the shortest way to strip attributes (including dimensions) off an object, although it's a bit of an abuse to use it this way.

like image 40
hadley Avatar answered Nov 30 '25 00:11

hadley