Search code examples
rfor-loopreplacesparse-matrixtransactional

Placing values from transaction list into a sparse matrix with a for loop


I generated a transaction list which includes a user ID, an item ID and a count how often the user-item pair occures:

UserID ItemID   N
X      S123     4
X      S134     3
X      S135    10
Y      S564     1
Y      S432     2
Z      S189     3

Out of this list I want to create a sparse matrix where the rows denote user IDs and columns denote ItemIDs and the cells are the respective count, or if the pair never occured 0.

I wrote a for loop which works but unfortunately takes forever with number of rows > 100.000 and number of columns > 2000:

for(i in 1:nrow(mat)){
  for(j in 1:ncol(mat)){

   r <- rownames(mat)[i]
   c <- colnames(mat)[j]

   mat[i,j] <- ifelse(length(trans[(trans$UserID == r) & (trans$ItemID ==  c), "N"]) > 0, trans[(trans$UserID == r) & (trans$ItemID == c), "N"], 0)    

 }
}

So, is there a faster way?


Solution

  • We can use sparseMatrix from Matrix

    library(Matrix)
    c1 <- as.numeric(factor(df1$ItemID, levels=unique(df1$ItemID)))
    r1 <- as.numeric(factor(df1$UserID, levels=unique(df1$UserID)))
    sP1 <- sparseMatrix(r1, c1, x=df1$N)
    dimnames(sP1) <- list(unique(df1$UserID), unique(df1$ItemID))
    
    sP1
    #   3 x 6 sparse Matrix of class "dgCMatrix"
    #    S123 S134 S135 S564 S432 S189
    #X    4    3   10    .    .    .
    #Y    .    .    .    1    2    .
    #Z    .    .    .    .    .    3