146

I have a matrix (32X48).

How can I convert the matrix into a single dimensional array?

zx8754
  • 52,746
  • 12
  • 114
  • 209
Alos
  • 2,657
  • 5
  • 35
  • 47

11 Answers11

260

Either read it in with 'scan', or just do as.vector() on the matrix. You might want to transpose the matrix first if you want it by rows or columns.

> m=matrix(1:12,3,4)
> m
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> as.vector(m)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
> as.vector(t(m))
 [1]  1  4  7 10  2  5  8 11  3  6  9 12
nico
  • 50,859
  • 17
  • 87
  • 112
Spacedman
  • 92,590
  • 12
  • 140
  • 224
  • It seems that `as.vector()` will flatten in column major order, ie for the 2x2 matrix `m`, will return `c(m[1, 1], m[2,1], m[1, 2], m[2, 2])`. This is therefore the exact opposite operation to converting a vector to a matrix with `matrix(vec)`, since `byrow` is false by default. – Migwell Mar 13 '21 at 12:25
48

try c()

x = matrix(1:9, ncol = 3)

x
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

c(x)

[1] 1 2 3 4 5 6 7 8 9
Greg
  • 11,564
  • 5
  • 41
  • 27
31

If we're talking about data.frame, then you should ask yourself are the variables of the same type? If that's the case, you can use rapply, or unlist, since data.frames are lists, deep down in their souls...

 data(mtcars)
 unlist(mtcars)
 rapply(mtcars, c) # completely stupid and pointless, and slower
aL3xa
  • 35,415
  • 18
  • 79
  • 112
16

array(A) or array(t(A)) will give you a 1-d array.

Himanshu
  • 31,810
  • 31
  • 111
  • 133
Tian
  • 161
  • 1
  • 2
13

you can use as.vector(). It looks like it is the fastest method according to my little benchmark, as follows:

library(microbenchmark)
x=matrix(runif(1e4),100,100) # generate a 100x100 matrix
microbenchmark(y<-as.vector(x),y<-x[1:length(x)],y<-array(x),y<-c(x),times=1e4)

The first solution uses as.vector(), the second uses the fact that a matrix is stored as a contiguous array in memory and length(m) gives the number of elements in a matrix m. The third instantiates an array from x, and the fourth uses the concatenate function c(). I also tried unmatrix from gdata, but it's too slow to be mentioned here.

Here are some of the numerical results I obtained:

> microbenchmark(
        y<-as.vector(x),
        y<-x[1:length(x)],
        y<-array(x),
        y<-c(x),
        times=1e4)

Unit: microseconds
                expr    min      lq     mean  median      uq       max neval
   y <- as.vector(x)  8.251 13.1640 29.02656 14.4865 15.7900 69933.707 10000
 y <- x[1:length(x)] 59.709 70.8865 97.45981 73.5775 77.0910 75042.933 10000
       y <- array(x)  9.940 15.8895 26.24500 17.2330 18.4705  2106.090 10000
           y <- c(x) 22.406 33.8815 47.74805 40.7300 45.5955  1622.115 10000

Flattening a matrix is a common operation in Machine Learning, where a matrix can represent the parameters to learn but one uses an optimization algorithm from a generic library which expects a vector of parameters. So it is common to transform the matrix (or matrices) into such a vector. It's the case with the standard R function optim().

David Bellot
  • 643
  • 7
  • 13
12

From ?matrix: "A matrix is the special case of a two-dimensional 'array'." You can simply change the dimensions of the matrix/array.

Elts_int <- as.matrix(tmp_int)  # read.table returns a data.frame as Brandon noted
dim(Elts_int) <- (maxrow_int*maxcol_int,1)
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
6

It might be so late, anyway here is my way in converting Matrix to vector:

library(gdata)
vector_data<- unmatrix(yourdata,byrow=T))

hope that will help

hema
  • 725
  • 1
  • 8
  • 20
5

Simple and fast since a 1d array is essentially a vector

result <- matrix[1:length(matrix)]
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
Jeff
  • 51
  • 1
  • 1
2

For anyone looking to produce not just the array, but the array with the corresponding Row and Column names I recommend the melt function as in this answer.

library(reshape2)
df.L <- melt( df, id.vars="New_name4_rownames",
               value.name="NAME_of_VALUE", variable.name="New_name4_colnames" )
print(df.L)

And then you can combine the names of the row and column as you like and use spread/pivot_wider to have the column names be a combination of the row+column names of the matrix and 1 row which is your vector.

df.L$Both <- paste0(df.L$New_name4_rownames, "_", df.L$New_name4_colnames)
df.sel <- df.L[,3:4] #select only values and combined column names
output1d <- pivot_wider(data = df.sel, names_from = Both, values_from = NAME_of_VALUE)
Kirk Geier
  • 499
  • 8
  • 15
1

You can use Joshua's solution but I think you need Elts_int <- as.matrix(tmp_int)

Or for loops:

z <- 1 ## Initialize
counter <- 1 ## Initialize
for(y in 1:48) { ## Assuming 48 columns otherwise, swap 48 and 32
for (x in 1:32) {  
z[counter] <- tmp_int[x,y]
counter <- 1 + counter
}
}

z is a 1d vector.

Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255
1

If you instead had a data.frame (df) that had multiple columns and you want to vectorize you can do

as.matrix(df, ncol=1)

Lee Sande
  • 457
  • 5
  • 15