7
votes

Grandes boucles accrochées dans R?

Supposons que je souhaite effectuer une simulation en utilisant la fonction suivante : xxx

pour très grand n , le calcul semble suspendre. Y a-t-il de meilleures façons de faire cela?

(Inspiré de: https://stat.thz.ch/pipermarin/r-help/2008-fèbre/155591.html )


0 commentaires

5 Réponses :


2
votes

Pour les boucles dans R sont notoirement lents, mais voici une autre question. Il est beaucoup plus rapide de prélever le vecteur de résultats, RES, plutôt à ajouter à res à chaque itération.

ci-dessous, nous pouvons comparer la vitesse de la version ci-dessus avec une version qui commence simplement avec un vecteur, res, de longueur n et change le ème élément pendant la boucle. p> xxx pré>

aussi, comme Sharpie pointe , nous pouvons rendre cela légèrement plus vite en utilisant des fonctions r, telles que Appliquer code> (ou ses proches, sapply code> et PARMPLY code>). P>

fn3 <- function(N) {
  sapply( 1:N, function( i ){ x <- rnorm(2); return( x[2] - x[1] ) } )
}
> system.time(res3 <- fn3(N))
   user  system elapsed 
  0.397   0.004   0.397 


2 commentaires

Quel est le problème avec la deuxième réponse dans ce thread de liste R: RES <- RNorm (10 ^ 6) -Rnorm (10 ^ 6)?


@ars: Vous avez absolument raison - cela donne la solution la plus rapide (par un ordre de grandeur). Les meilleurs conseils seraient 1. Utilisez des fonctions qui fonctionnent naturellement sur les vecteurs (comme RNorm. 2. omettre cela, utilisez une fonction * Appliquer; 3. omettre cela, utilisez A pour la boucle avec préallocation.



9
votes

L'efficacité des boucles peut être considérablement augmentée en R grâce à l'utilisation des fonctions d'application qui traitent essentiellement des vecteurs entiers de données à la fois plutôt que de boucler à travers eux. Pour la boucle indiquée ci-dessus, deux opérations de base se produisent lors de chaque itération: xxx pré>

dans ce cas, la fonction appropriée serait sapply () code>. sapply () code> fonctionne sur une liste d'objets, tels que le vecteur généré par l'instruction LOOP 1: n code> et renvoie un vecteur des résultats: p>

sapply( 1:N, function( i ){ x <- rnorm(2); return( x[2] - x[1] ) } )


0 commentaires

2
votes

Parfois, la boucle n'est pas nécessaire. Puisque RNorm donne un échantillon IID (théoriquement), vous obtiendrez le même résultat (échantillonnage x-y où x et y sont n (0,1)) en faisant: xxx


0 commentaires

4
votes

Développer sur mon commentaire à la réponse de chris_dubois, voici quelques informations de synchronisation: xxx pré>

contraste avec FN3 à partir de cette même réponse: p>

> system.time(res3 <- fn3(50000))
user  system elapsed
1.33    0.01    1.36


3 commentaires

Bons points. Mon intention initiale pour cette question était de mettre en évidence l'idée que la préallocation peut être une bonne chose. Comme vous l'avez souligné, cet exemple particulier peut être facilement fait avec uniquement les opérations vectorielles. Il serait agréable d'avoir quelques autres exemples dans lesquels des personnes affichent des alternatives pour optimiser le code R (genre de comme wiki.r-project.org/rwiki/... ). Les pensées?


Hé, c'est une bonne idée - je suis malheureusement ignorant de ce wiki. Je sais que j'ai rencontré une boucle de couple aux optimisations de vecteur en lisant le code écrit par d'autres - récemment en regardant du code par Wegherty pour la construction de variogrammes. J'ai tendance à supposer que c'est des connaissances courantes et non remarquables pour les autres, mais il vaut mieux se tromper du côté de la documenter. Je vais traverser mes fichiers et trouver quelque chose de spécifique pour ajouter au wiki, espérons-le ce week-end. Avez-vous des pensées sur la façon de le structurer? Devrions-nous simplement créer une page "conseils vectorisants" et le casser si nécessaire?


appliquer peut être aussi rapide qu'une boucle pour boucle, mais acadrély et (surtout) vapply sont généralement plus rapides car ils sont mis en œuvre dans C et ont Optimisé l'appel de la fonction amusant . Mais cela ne compte que lorsque le temps réel passé dans amusant est petit.



0
votes

Peut-être que le remplacement le plus efficace de votre fonction serait simplement le suivant: xxx

qui est deux fois plus rapide que de la différence de variation normale IID. Plus généralement, si votre objectif est de lancer des simulations simples, vectorielles / array préallocation et appels vers des fonctions natives accélèrent considérablement le processus.

Si vous souhaitez effectuer des simulations de Monte-Carlo pour des estimations statistiques (E.G., MCMC), R a un certain nombre de packages natifs. Pour la simulation stochastique générale, je ne suis pas au courant des paquets R, mais vous pouvez essayer d'essayer SIMPY ( http: //simpy.sourceforge .NET / ), qui est excellent.


0 commentaires