# Sparse matrix in R based on the data frame

Suppose I have book ratings in the form of data frame (where 0 means no rating):

$$\begin{array}{|c|c|c|} \hline \textbf{User.ID}& \textbf{ISBN} & \textbf{Book.Rating} \\ \hline 276725 & 034545104X & 0 \\ \hline 276726 & 0155061224 & 5 \\ \hline 276725 & 3257224281 & 7 \\ \hline ... & ... & ... \\ \hline \end{array}$$

In what easiest way can I get the form as below (I want to use it to create a realRatingMatrix object) ?

$$\begin{array}{|c|c|c|c|c|} \hline \ & \textbf{034545104X} & \textbf{0155061224} & \textbf{3257224281} & ...\\ \hline \textbf{276725} & . & 3 & 7 & ...\\ \hline \textbf{276726} & 5 & 5 & . & ...\\ \hline ... & ... & ... & ... & ...\\ \hline \end{array}$$

Your data looks like this at the moment:

data <- data.frame(User_Id = c(276725, 276726, 276725, 276726, 276725),
ISBN = c("A", "B", "C", "A", "B"),
Book_Rating = c(0, 5, 7, 5, 3))

> data

User_Id ISBN Book_Rating
1  276725    A           0
2  276726    B           5
3  276725    C           7
4  276726    A           5
5  276725    B           3


With the following commands you can create a dgCMatrix, required as input for a realRatingMatrix object.

library(Matrix)
data_sparse = sparseMatrix(as.integer(data$$User_Id), as.integer(data$$ISBN), x = data$$Book_Rating) colnames(data_sparse) = levels(data$$ISBN)
rownames(data_sparse) = levels(data$User_Id) > data_sparse 276726 x 3 sparse Matrix of class "dgCMatrix" A B C [1,] . . . [2,] . . . [3,] . . . .............................. ........suppressing rows in show(); maybe adjust 'options(max.print= *, width = *)' .............................. [276722,] . . . [276723,] . . . [276724,] . . . [276725,] 0 3 7 [276726,] 5 5 .  After that you can call the command new("realRatingMatrix", data = data_sparse)  Bear in mind that this matrix starts at one and it's only populated in two rows (276725 and 276726) but the rest of the columns from 1 to 276725 exist. If you don't want to use User_Id as indices you will have to create new indices and use those instead and have one User_Id correspond to a new index. That means if User_Id starts at, for instance, [11, 18...] then it'd become User_Id 11 = New_Index 1, User_Id 18 = New_Index = 2. Use New_Index instead of User_Id and you're done. If that's the case then data should end up looking like this: data <- data.frame(User_Id = as.factor(c(276725, 276726, 276725, 276726, 276725)), ISBN = c("A", "B", "C", "A", "B"), Book_Rating = c(0, 5, 7, 5, 3), New_Index = c(1, 2, 1, 2, 1)) > data User_Id ISBN Book_Rating New_Index 1 276725 A 0 1 2 276726 B 5 2 3 276725 C 7 1 4 276726 A 5 2 5 276725 B 3 1 library(Matrix) data_sparse = sparseMatrix(as.integer(data$$New_Index), as.integer(data$$ISBN), x = data$$Book_Rating) colnames(data_sparse) = levels(data$$ISBN) rownames(data_sparse) = levels(data$User_Id)

> data_sparse

2 x 3 sparse Matrix of class "dgCMatrix"
A B C
276725 0 3 7
276726 5 5 .

• Thank you for your answer. I have one more problem. Unfortunately, the levels function probably does not really match my problem because it spreads User_Id between all numbers between 1 and 276726. But I do not have all of these values in the original User_Id for example 11, 18 etc. Or, do you think that I should only use a subset of rows from dgCMatrix to create a realRatingMatrix ? Commented Dec 24, 2018 at 15:27