R преобразовать матрицу или фрейм данных в sparseMatrix
У меня есть обычная матрица (не разреженная), которую я хотел бы преобразовать в sparseMatrix
(с использованием Matrix
пакет). Есть ли функция для этого или мне нужно сделать несколько циклов?
ех.
> regMat <- matrix(0, nrow=10, ncol=10)
> regMat[3,5] <- round(runif(1),2)*100
> regMat[2,8] <- round(runif(1),2)*100
> regMat[8,4] <- round(runif(1),2)*100
> regMat[1,6] <- round(runif(1),2)*100
> regMat[7,4] <- round(runif(1),2)*100
> regMat
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 0 0 0 0 49 0 0 0 0
[2,] 0 0 0 0 0 0 0 93 0 0
[3,] 0 0 0 0 20 0 0 0 0 0
[4,] 0 0 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0 0 0 0
[6,] 0 0 0 0 0 0 0 0 0 0
[7,] 0 0 0 8 0 0 0 0 0 0
[8,] 0 0 0 14 0 0 0 0 0 0
[9,] 0 0 0 0 0 0 0 0 0 0
[10,] 0 0 0 0 0 0 0 0 0 0
Какие-либо предложения?
1 ответ
Вот два варианта:
library(Matrix)
A <- as(regMat, "sparseMatrix") # see also `vignette("Intro2Matrix")`
B <- Matrix(regMat, sparse = TRUE) # Thanks to Aaron for pointing this out
identical(A, B)
# [1] TRUE
A
# 10 x 10 sparse Matrix of class "dgCMatrix"
#
# [1,] . . . . . 45 . . . .
# [2,] . . . . . . . 59 . .
# [3,] . . . . 95 . . . . .
# [4,] . . . . . . . . . .
# [5,] . . . . . . . . . .
# [6,] . . . . . . . . . .
# [7,] . . . 23 . . . . . .
# [8,] . . . 63 . . . . . .
# [9,] . . . . . . . . . .
# [10,] . . . . . . . . . .
Ответ Джоша в порядке, но здесь есть больше вариантов и объяснений.
Nit Picky "У меня есть регулярная матрица (не разреженная)..." На самом деле у вас есть разреженная матрица (матрица с большей частью 0); это просто в несжатом формате. Ваша цель - поместить его в сжатый формат хранения.
Разреженные матрицы могут быть сжаты в несколько форматов хранения. Сжатый разреженный столбец (CSC) и Сжатый разреженный ряд (CSR) являются двумя доминирующими форматами. as(regMat, "sparseMatrix")
преобразует вашу матрицу в тип dgCMatrix
который является сжатым разреженным столбцом. Обычно это то, что вы хотите, но я предпочитаю быть откровенным об этом.
library(Matrix)
matCSC <- as(regMat, "dgCMatrix") # compressed sparse column CSC
matCSC
10 x 10 sparse Matrix of class "dgCMatrix"
[1,] . . . . . 57 . . . .
[2,] . . . . . . . 27 . .
[3,] . . . . 90 . . . . .
[4,] . . . . . . . . . .
[5,] . . . . . . . . . .
[6,] . . . . . . . . . .
[7,] . . . 91 . . . . . .
[8,] . . . 37 . . . . . .
[9,] . . . . . . . . . .
[10,] . . . . . . . . . .
matCSR <- as(regMat, "dgRMatrix") # compressed sparse row CSR
matCSR
10 x 10 sparse Matrix of class "dgRMatrix"
[1,] . . . . . 57 . . . .
[2,] . . . . . . . 27 . .
[3,] . . . . 90 . . . . .
[4,] . . . . . . . . . .
[5,] . . . . . . . . . .
[6,] . . . . . . . . . .
[7,] . . . 91 . . . . . .
[8,] . . . 37 . . . . . .
[9,] . . . . . . . . . .
[10,] . . . . . . . . . .
Хотя они выглядят и ведут себя одинаково на поверхности, внутри они хранят данные по-разному. CSC быстрее извлекает столбцы данных, а CSR быстрее извлекает строки. Они также занимают различное количество места в зависимости от структуры ваших данных.
Кроме того, в этом примере вы конвертируете несжатую разреженную матрицу в сжатую. Обычно вы делаете это для экономии памяти, поэтому построение несжатой матрицы просто для преобразования ее в сжатую форму противоречит цели. На практике более распространенным является создание сжатой разреженной матрицы из таблицы триплетов (строка, столбец, значение). Вы можете сделать это с помощью матрицы sparseMatrix()
функция.
# Make data.frame of (row, column, value) triplets
df <- data.frame(
rowIdx = c(3,2,8,1,7),
colIdx = c(5,8,4,6,4),
val = round(runif(n = 5), 2) * 100
)
df
rowIdx colIdx val
1 3 5 90
2 2 8 27
3 8 4 37
4 1 6 57
5 7 4 91
# Build CSC matrix
matSparse <- sparseMatrix(
i = df$rowIdx,
j = df$colIdx,
x = df$val,
dims = c(10, 10)
)
matSparse
10 x 10 sparse Matrix of class "dgCMatrix"
[1,] . . . . . 57 . . . .
[2,] . . . . . . . 27 . .
[3,] . . . . 90 . . . . .
[4,] . . . . . . . . . .
[5,] . . . . . . . . . .
[6,] . . . . . . . . . .
[7,] . . . 91 . . . . . .
[8,] . . . 37 . . . . . .
[9,] . . . . . . . . . .
[10,] . . . . . . . . . .
Shameless Plug - у меня есть статья в блоге, рассказывающая об этом и многом другом, если вам интересно.
По матрице у кого-то уже есть ответ.
Для таблицы data.table есть пакет, который выполнил эту работу.
library(Matrix)
library(mltools)
x = data.table()
sparseM <- sparsify(x)