2013-06-28 3 views
13

Mam macierz czynników w R i chcę ją przekonwertować na macierz zmiennych atrapowych 0-1 dla wszystkich możliwych poziomów każdego z czynników.R: konwersja macierzy rzadkiej

Jednak ta "obojętna" matryca jest bardzo duża (91690x16593) i bardzo rzadka. Muszę przechowywać go w rzadkiej macierzy, w przeciwnym razie nie mieści się w moim 12 GB pamięci RAM.

Obecnie używam następujący kod i działa bardzo dobrze i zajmuje kilka sekund:

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) 

Jednak chcę użyć pakietu e1071 w badania i ostatecznie zapisać macierz libsvm formatu z write.matrix.csr() , więc najpierw muszę przekonwertować moją rzadką macierz na format SparseM.

próbowałem zrobić:

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

ale bardzo szybko wypełnia moje RAM i ostatecznie R awarii. Podejrzewam, że wewnętrznie, as.matrix.csr najpierw konwertuje rzadką macierz na gęstą matrycę, która nie mieści się w mojej pamięci komputera.

Inną alternatywą byłoby utworzenie mojej macierzy rozproszonej bezpośrednio w formacie SparseM.
Próbowałem as.matrix.csr(X_factors), ale nie akceptuję ramki danych czynników.

Czy istnieje odpowiednik sparse.model.matrix(~.-1, data = X_factors) w pakiecie SparseM? Szukałem w dokumentacji, ale nie znalazłem.

Odpowiedz

18

Dość podstępna, ale myślę, że ją mam.

Zacznijmy rozrzedzony matrycy z pakietu Matrix:

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

Pakiet Matrix używa formatu kompresji kolumny zorientowanych, a SparseM obsługuje oba formaty kolumn i wierszy zorientowane i posiada funkcje, które można łatwo obsługiwać konwersja z jednego formatu na drugi.

Więc będziemy najpierw przekonwertować nasze kolumny zorientowanych Matrix do kolumny zorientowanych SparseM matrycy: po prostu trzeba być ostrożnym wywołanie odpowiedniego konstruktora i zauważając, że oba pakiety stosować różne konwencje dla indeksów (start przy 0 lub 1):

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

Następnie zmiana formatu kolumna zorientowanych wiosłować zorientowanych:

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

I gotowe! Możesz sprawdzić, czy te dwie macierze są identyczne (na moim małym przykładzie), wykonując:

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

Wszystko działało idealnie. Dziękuję za szybką odpowiedź. –