2010-05-06 5 views
10

Je suis en train d'implémenter un algorithme qui implique beaucoup d'ajouter et de supprimer des choses des ensembles. En R, c'est lent parce que, autant que je sache, ajouter ou supprimer des choses d'un vecteur est lent, puisque le vecteur entier doit être ré-alloué. Y a-t-il un moyen de le faire plus efficacement? Editer: Ma solution actuelle consiste à utiliser un vecteur booléen de la même longueur que la liste des choses qui peuvent être dans l'ensemble, et à l'utiliser comme table d'appartenance.Ajout ou suppression efficace d'éléments dans un vecteur ou une liste dans R?

+1

Y a-t-il une chance que vous fournissiez le code exact? De votre question je ne peux pas savoir si vous utilisez une liste ou des vecteurs, comment vous ajoutez ou supprimez (quelle fonction?) Éléments, comment fonctionne votre solution actuelle (recréer un vecteur logique à la place ajouter/supprimer à l'original?)? Plus d'informations que vous fournissez, plus d'optimisation peut être faite. – Marek

+0

nouvelle version de R devrait être mieux à ce sujet. Est-ce vrai? – userJT

+0

Je doute que redimensionner un vecteur à plusieurs reprises que les éléments sont ajoutés ou supprimés de lui sera jamais rapide. –

Répondre

12

Chapitre 2 The R Inferno a quelques commentaires intéressants à ce sujet, y compris les objets perdiodic de plus en plus de re déduire la fragmentation de la mémoire et les frais généraux d'allocation. Si vous savez quelle est la taille finale de l'ensemble, alors la méthode que vous suggérez est probablement la meilleure - subset de l'univers entier en utilisant un vecteur d'adhésion approprié. Difficile de savoir quoi de mieux sans voir exactement ce que vous essayez de faire.

+0

+1 pour le référencement The R Inferno – Stedy

+0

Je me suis retrouvé avec un vecteur booléen représentant l'appartenance à un ensemble. –

+0

pourriez-vous mettre à jour le lien?'404 Not Found' – Shreyans

11

Si vous le pouvez, initialiser un vecteur de sorte qu'il ait une longueur égale à sa longueur maximale pendant l'algorithme peut aider.

par exemple.

vec <- rep(NA,10) 
vec[1:3] <- 1:3 
vec[4:5] <- 4:5 
vec[6:10] <- 6:10 

plutôt que

vec <- 1:3 
vec <- c(vec,4:5) 
vec <- c(vec,6:10) 

comparer

> system.time({vec <- rep(NA,10^4); for (i in 1:(10^4)) vec[i] <- i }) 
    user system elapsed 
    0.043 0.001 0.044 

à

> system.time({vec <- NULL; for (i in 1:(10^4)) vec <- c(vec,i) }) 
    user system elapsed 
    0.249 0.089 0.335 
+0

Mais je pourrais éventuellement enlever n'importe quel élément dans le vecteur, pas seulement le dernier. –

+1

Bien sûr. Les boucles ne sont que des exemples pour montrer la différence entre l'initialisation d'un vecteur et la construction d'un vecteur avec affectation répétée. Je n'ai évidemment pas vu votre algorithme mais cette méthode devrait quand même fonctionner, car 'i' pourrait être n'importe quel nombre à n'importe quel point de votre algorithme. Cela dépend seulement de connaître la longueur de votre vecteur pour commencer. En outre, au lieu de l'enlever, vous devez simplement affecter cet élément à 'NA' et conserver un vecteur de même longueur. – wkmor1

+0

Vous n'avez pas besoin d'utiliser 'eval/parse', il suffit de prendre l'expression entre accolades, c'est-à-dire:' system.time ({vec <- rep (NA, 10^4), pour (i en 1 :(10^4)) vec [i] <- i}) ' – Marek

3

Il est difficile de dire ce que vous voulez. Peut-être que vous voulez vraiment des commandes de pile comme pousser et pop. Ce qui suit n'est pas ça. Mais c'est une solution rapide. Allouer un vecteur assez grand pour contenir tous vos articles du type dont vous avez besoin. Définissez chaque valeur sur NA. L'ajout d'éléments est simple. La suppression d'éléments les redéfinit sur NA. L'utilisation du vecteur est juste na.omit(myVec)

myVec <- numeric (maxLength) # a vector of maximum length 

is.na(myVec) <- 1:maxLength # set every item in myVec to NA 

myVec[c(2,6,20)] <- 5   # add some values 

na.omit(myVec) 

#This will also work if you can initialize all of your values to something that you know you won't need. 
+0

Une pile R: http://rosettacode.org/wiki/Stack#R –

+1

@John: 'myVec <- rep (NA, maxLength)' remplace vos deux premières lignes plus proprement. Aussi, qu'est-ce qu'il y a avec la grosse écriture? –

Questions connexes