# 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}$$

## 1 Answer

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 ? Dec 24, 2018 at 15:27
• As suggested at the end: " 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 User_Id 11 = New_Index = 1, User_Id 18 = New_Index = 2. Use New_Index instead of User_Id and you're done. If you want to add more information about your question then you should edit your question instead. Check the answer edit for more information. Dec 24, 2018 at 20:16