2017-05-21 4 views
1

J'ai une trame de données avec 3 colonnes, dont deux représentent les indices i, j dans une matrice. Pour chaque ligne de la trame de données, je voudrais remplir le i correspondant, la valeur j dans une matrice à 1.Remplir les valeurs matricielles de la trame de données de manière vectorisée

partage des données et de la matrice ci-dessous, que je pense, il sera plus facile de décrire le problème:

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 

La colonne-i est user_id et la j-colonne est item_id. Donc pour la première rangée, je voudrais pour M [3219, 174] = 1, alors je voudrais M [144, 10] = 1, etc. Je voudrais le faire sans boucle for, ce qui est trop lent compte tenu de la taille de ma matrice.

Pour référence, ce que je fais actuellement est:

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

Cependant, mon problème des échelles assez grandes, ce qui est trop lent pour mon problème. Toute aide est grandement appréciée! Merci

EDIT: J'ai essayé quelque chose le long des lignes de:

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

mais il ne fonctionne pas aussi bien que j'espère (prend encore plus longtemps que la boucle for).

+0

Êtes-vous sûr que vous avez besoin de la matrice pour contenir des indices pour ids qui ne sont pas présents? Vous vous retrouvez avec une très grande matrice, très clairsemée, qui peut ne pas être très utile en fonction de ce que vous allez en faire. – Marius

Répondre

3

Essayez ceci:

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

wow c'est rapide - c'est génial car je peux utiliser ce format pour beaucoup de mes problèmes. Merci 989! – Canovice