Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to coerce matrix to integer matrix in R

I just realized that if you create a matrix with integer values, they are rather stored as numeric.

a <- matrix(c(0,1,0,1), ncol=2)
class(a[1,]) # numeric

a matrix of integers need half the amount of memory (for large dimensions). The following function coerces all values to integers:

forceMatrixToInteger <- function(m){
    apply (m, c (1, 2), function (x) {
         (as.integer(x))
    })
}

a <- forceMatrixToInteger(a)

class(a[1,]) # integer

I wanted to know if you can think of any other way to do this, and if it would be faster or more memory efficient.

sessionInfo

R version 3.2.3 (2015-12-10)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.3 (El Capitan)

EDIT: First Test

I defined a function that does what Richard Scriven answer describes, and the one I defined, and tested speed.

exp_size <- 4
exp_reps <- 3 
mat <- matrix(sample(c(0,1), 10^exp_size, replace=TRUE),ncol=10^(exp_size/2))

fun1<-function(){
    mode(mat) <- 'integer'
}

time <- proc.time()
    for (i in 1:10^exp_reps){
    fun1()
}
time <- proc.time()-time
print('Results fun1:')
print(time)

 print(time)
 # user  system elapsed 
 # 0.096   0.035   0.132 

fun2 <- function(){
    apply (mat, c (1, 2), function (x) {
         (as.integer(x))
    })
}

time <- proc.time()
for (i in 1:10^exp_reps){
    fun2()
}
time <- proc.time()-time
print('Results fun2:')
print(time)

# user  system elapsed 
# 22.592   0.148  22.775 

There is a clear winner.

like image 774
latorrefabian Avatar asked Apr 29 '16 17:04

latorrefabian


1 Answers

If you do c(0, 1, 0, 1), it seems like you would be creating integers, but you are actually creating a vector of doubles. For integers you would have to use c(0L, 1L, 0L, 1L), or rep(0:1, 2) (since : creates a vector of integers). To change your matrix to integer, you can change its internal storage mode.

a <- matrix(c(0,1,0,1), ncol=2)
object.size(a)
# 232 bytes
mode(a) <- "integer"
object.size(a)
# 216 bytes

I don't know how fast it is, but it's pretty easy.

like image 113
Rich Scriven Avatar answered Oct 16 '22 19:10

Rich Scriven