对于无望的头衔感到抱歉..
我有一个看起来像的数据集:
|userId|movieId|rating|genre1|genre2|
|1 |13 |3.5 |1 |0 |
|1 |412 |2.5 |1 |1 |
|2 |4 |3.0 |0 |1 |
|3 |412 |2.5 |1 |1 |
|4 |13 |4.5 |1 |0 |
|4 |412 |5 |1 |1 |
等等......
并非每个用户都为每部电影评分。
我想将其转换为如下的矩阵:
| |1 |2 |3 |4 |
|4 | |3 | | |
|13 |2.5| | |4.5|
|412| | | |5 |
所以我将userId作为列,将movieId作为行,关联值为给定的评级。
最好的方法是什么?
编辑:ID是非顺序的。有140k用户和28k电影。
答案 0 :(得分:5)
如果您有多个用户和多部电影,构建matrix
时可能会很容易耗尽内存。比如说用户是1000而不同的电影是1000.你最终会得到一个包含1M条目的matrix
,其中大部分都会丢失(因为不是每个用户都看过每部电影)。
如果您的数据集很大,那么sparseMatrix
包中的Matrix
就可以了。如果用户和电影ID都是顺序的(即它们以1开头并以不同条目的数量结束),那么构建它是很简单的。使用@StevenBeauprédata
:
require(Matrix)
mat<-sparseMatrix(df$userId,df$movieId,x=df$rating)
如果id不是连续的:
mat<-sparseMatrix(as.integer(factor(df$userId)),
as.integer(factor(df$movieId)),x=df$rating)
您基本上可以对matrix
执行任何sparseMatrix
操作。
答案 1 :(得分:2)
尝试
library(dplyr)
library(tidyr)
df %>%
select(-(genre1:genre2)) %>%
spread(userId, rating, fill = "")
给出了:
# movieId 1 2 3 4
#1 4 3
#2 13 3.5 4.5
#3 412 2.5 2.5 5
数据强>
df <- structure(list(userId = c(1L, 1L, 2L, 3L, 4L, 4L), movieId = c(13L,
412L, 4L, 412L, 13L, 412L), rating = c(3.5, 2.5, 3, 2.5, 4.5,
5), genre1 = c(1L, 1L, 0L, 1L, 1L, 1L), genre2 = c(0L, 1L, 1L,
1L, 0L, 1L)), .Names = c("userId", "movieId", "rating", "genre1",
"genre2"), class = "data.frame", row.names = c(NA, -6L))