2017-04-18 2 views
1

Je prends une grande matrice de réseau (dense) et la convertir en un edgelist. Pourtant, quand je le fais, la mémoire allouée dans R semble fou. Dans mon cas, j'ai une matrice de 12 Mo (1259 x 1259) qui, une fois convertie en edgelist (i, j, w), prend 71 Mo de mémoire! J'utilise le paquet igraph pour effectuer les opérations, mais je ne pense pas que cela soit lié à ça. Voici ce que je fais avec des données maquillées.R allocation de mémoire avec cbind

library(igraph) 
A <- matrix(runif(25), 5, 5) 
A <- A %*% t(A) 
diag(A) <- 0 

I fait le symétrique de la matrice et diagonale 0 parce que c'est ce que mes données ressemble, mais je ne pense pas qu'il importe à cette question. Ici, je utiliser igraph:

# using igraph here 
adj <- graph.adjacency(as.matrix(A),weighted=TRUE) 
object.size(A) # 400 bytes 
object.size(adj) # 2336 bytes 

Je reçois que le igraph objet adj sera plus grand. Ce n'est pas le problème. Pourquoi la mémoire sur adj_w est-elle tellement plus grande? Il ne semble même pas être linéaire puisque ici, l'original à la finale est de 400 octets à 1016 octets mais dans mes (plus grandes) données il est de 12 Mo à 71 Mo.

FYI: J'utilise RStudio localement sur un Macbook Pro avec les dernières versions (je l'ai juste installé la semaine dernière).

Répondre

3

adj_w est plus grand car cbind a ajouté un nom de colonne. Retirez-le et vous êtes de retour à la bonne taille.

head(adj_w) 
#     w 
# [1,] 1 2 1.189969 
# [2,] 1 3 1.100843 
# [3,] 1 4 0.805436 
# [4,] 1 5 1.001632 
# [5,] 2 1 1.189969 
# [6,] 2 3 1.265916 

object.size(adj_w) 
# 1016 bytes 

attributes(adj_w) 
# $dim 
# [1] 20 3 
# 
# $dimnames 
# $dimnames[[1]] 
# NULL 
# 
# $dimnames[[2]] 
# [1] "" "" "w" 
# 
# 

adj_w2 <- adj_w 
dimnames(adj_w2) <- NULL 
object.size(adj_w2) 
# 680 bytes 

Pour éviter l'ajout du nom de colonne automatique, vous pouvez d'abord convertir votre vecteur à une matrice ...

adj_w3 <- cbind(el, matrix(w)) 
object.size(adj_w3) 
# 680 bytes 

... ou bien passer l'argument deparse.level = 0-cbind.

adj_w4 <- cbind(el, w, deparse.level = 0) 
object.size(adj_w4) 
# 680 bytes 
+0

Vous avez répondu à la partie technique. Je faisais aussi une mauvaise hypothèse logique. Dans mon esprit, A et adj_w représentent le même réseau et devraient donc être de la même taille, mais A est 400 b et adj_w (même avec votre ajustement) est 680 b. Pourquoi tellement plus gros? L'erreur que j'ai faite était que maintenant l'indexation doit être stockée. Dans A, chaque dimension 1: N est implicite, non stockée, mais maintenant les deux premières colonnes d'adj_w stockent ces index, ce qui triple presque la taille de stockage. –