2013-06-28 7 views
13

Ho una matrice di fattori in R e voglio convertirla in una matrice di variabili dummy 0-1 per tutti i possibili livelli di ciascun fattore.R: conversione matrice sparsa

Tuttavia questa matrice "fittizia" è molto grande (91690x16593) e molto sparsa. Ho bisogno di memorizzarlo in una matrice sparsa, altrimenti non si adatta ai miei 12GB di RAM.

Attualmente, sto usando il seguente codice e funziona molto bene e richiede pochi secondi:

library(Matrix) 
X_factors <- data.frame(lapply(my_matrix, as.factor)) 
#encode factor data in a sparse matrix 
X <- sparse.model.matrix(~.-1, data = X_factors) 

Tuttavia, voglio usare il pacchetto E1071 in R, e, infine, salvare questa matrice per libsvm formato con write.matrix.csr() , quindi prima devo convertire la mia matrice sparsa nel formato SparseM.

ho cercato di fare:

library(SparseM) 
X2 <- as.matrix.csr(X) 

ma riempie molto rapidamente la mia RAM e, infine, R si blocca. Sospetto che internamente, as.matrix.csr converta prima la matrice sparsa in una matrice densa che non si adatta alla memoria del mio computer.

Un'altra mia alternativa sarebbe quella di creare la mia matrice sparsa direttamente nel formato SparseM.
Ho provato as.matrix.csr(X_factors) ma non accetta un data-frame di fattori.

Esiste un valore equivalente a sparse.model.matrix(~.-1, data = X_factors) nel pacchetto SparseM? Ho cercato nella documentazione ma non l'ho trovato.

risposta

18

Abbastanza complicato ma penso di averlo capito.

Iniziamo con una matrice sparsa dal pacchetto Matrix:

i <- c(1,3:8) 
j <- c(2,9,6:10) 
x <- 7 * (1:7) 
X <- sparseMatrix(i, j, x = x) 

Il pacchetto Matrix utilizza un formato di compressione colonna orientato, mentre SparseM supporta entrambi i formati di colonna e di riga e segue funzioni che possono maneggiare facilmente il conversione da un formato all'altro.

Quindi per prima convertire la nostra colonna-orientati Matrix in una SparseM matrice di colonna-oriented: abbiamo solo bisogno di stare attenti chiamando il costruttore giusto e notando che entrambi i pacchetti utilizzano convenzioni diverse per gli indici (inizio alle 0 o 1):

X.csc <- new("matrix.csc", ra = [email protected], 
          ja = [email protected] + 1L, 
          ia = [email protected] + 1L, 
          dimension = [email protected]) 

Poi, il cambiamento dal formato di colonna-oriented per remare-oriented:

X.csr <- as.matrix.csr(X.csc) 

E il gioco è fatto! È possibile verificare che le due matrici siano identiche (sul mio piccolo esempio) facendo:

range(as.matrix(X) - as.matrix(X.csc)) 
# [1] 0 0 
+0

Ha funzionato perfettamente. Grazie per la veloce risposta. –