Подтвердить что ты не робот

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

Любые предложения?

4b9b3361

Ответ 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,] . . .  .  .  . .  . . .

Ответ 2

Джош ответил хорошо, но здесь есть больше вариантов и объяснений.

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() функции Matrix 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 - у меня есть статья в блоге, рассказывающая об этом и многом другом, если вам интересно.

Ответ 3

Для матрицы у кого-то уже есть ответ.

Для data.table есть пакет, который сделал эту работу.

library(Matrix)
library(mltools)
x = data.table()
sparseM <- sparsify(x)