以矢量化方式从数据帧填写矩阵值

时间:2017-05-21 22:54:36

标签: r matrix dataframe vectorization

我有一个包含3列的数据帧,其中两列代表矩阵中的i,j索引。对于数据帧的每一行,我想将矩阵中相应的i,j值填充为1.

在下面分享数据和矩阵,我认为这样可以更容易地描述问题:

data = structure(list(sale_id = c(0L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 10L, 10L, 11L, 11L, 11L, 
12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 14L, 15L, 16L, 16L, 
17L, 17L, 17L, 17L, 17L, 18L, 18L, 19L, 19L, 20L, 20L, 21L, 22L, 
22L, 23L, 23L, 23L, 24L, 24L, 25L, 25L, 26L, 26L, 27L, 27L, 28L, 
28L, 29L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 31L, 31L, 32L, 32L, 
33L, 33L, 33L, 33L, 33L, 33L, 34L, 34L), user_id = c(3219L, 144L, 
2884L, 2884L, 2155L, 2155L, 2155L, 2155L, 2817L, 2817L, 2817L, 
2817L, 2817L, 2817L, 144L, 144L, 2850L, 2850L, 2850L, 2850L, 
2850L, 2850L, 2850L, 2850L, 2850L, 144L, 144L, 144L, 144L, 144L, 
144L, 144L, 144L, 2817L, 2817L, 2075L, 2075L, 2546L, 2546L, 2546L, 
2687L, 2687L, 2687L, 2687L, 2687L, 2687L, 2687L, 2687L, 170L, 
2546L, 1963L, 144L, 144L, 1825L, 1825L, 1825L, 1825L, 1825L, 
144L, 144L, 2155L, 2155L, 2546L, 2546L, 144L, 2155L, 2155L, 144L, 
144L, 144L, 3182L, 3182L, 3343L, 3343L, 170L, 170L, 2155L, 2155L, 
2793L, 2793L, 1564L, 2250L, 2250L, 2250L, 2250L, 2250L, 2250L, 
2250L, 3083L, 3083L, 2075L, 2075L, 144L, 144L, 144L, 144L, 144L, 
144L, 829L, 829L), item_id = c(174L, 10L, 179L, 162L, 171L, 182L, 
179L, 185L, 199L, 179L, 195L, 174L, 162L, 198L, 144L, 69L, 57L, 
47L, 83L, 80L, 10L, 117L, 14L, 90L, 88L, 186L, 167L, 192L, 142L, 
162L, 173L, 151L, 134L, 191L, 166L, 118L, 128L, 98L, 95L, 119L, 
130L, 154L, 155L, 181L, 120L, 118L, 77L, 120L, 101L, 31L, 139L, 
10L, 30L, 182L, 179L, 139L, 173L, 171L, 80L, 39L, 26L, 69L, 163L, 
151L, 175L, 150L, 148L, 121L, 147L, 88L, 183L, 177L, 132L, 167L, 
176L, 172L, 57L, 78L, 98L, 99L, 118L, 102L, 141L, 97L, 99L, 79L, 
32L, 17L, 16L, 30L, 66L, 54L, 57L, 91L, 81L, 39L, 92L, 123L, 
87L, 62L)), .Names = c("sale_id", "user_id", "item_id"), row.names = c(NA, 
100L), class = "data.frame")

M = matrix(0, nrow = max(data$user_id), ncol = max(data$item_id))

head(data, n = 6)
    sale_id user_id item_id
1         0    3219     174
2         1     144      10
3         2    2884     179
4         2    2884     162
5         3    2155     171
6         3    2155     182

i列是user_id,j列是item_id。所以对于第一行,我想M [3219,174] = 1,然后我想M [144,10] = 1,等等。我想这样做没有for循环,这太慢了鉴于我的矩阵的大小。

作为参考,我目前正在做的是:

for(i in 1:nrow(data)) {
  M[data$user_id[i], data$item_id[i]] = 1
}

然而,我的问题规模相当大,这对我的问题来说太慢了。任何帮助是极大的赞赏!感谢

编辑:我尝试了以下方面的内容:

apply(data, 1, FUN = function(x) M[x[2],x[3]] = 1)

但它并没有像我希望的那样有效(比for-loop更长)。

1 个答案:

答案 0 :(得分:3)

试试这个:

M[cbind(data$user_id,data$item_id)] <- 1