2017-08-23 3 views
-3

Je voudrais convertir un pour un cycle dans une opération plus rapide telle qu'appliquer.convertir un pour cycle en R

Voici mon code

for(a in 1:dim(k)[1]){ 

for(b in 1:dim(k)[2]){ 

if((k[a,b,1,1]==0) & (k[a,b,1,2]==0) & (k[a,b,1,3]==0)){ 

    k[a,b,1,1]<-1 

    k[a,b,1,2]<-1 

    k[a,b,1,3]<-1 

     } 
     } 
      } 

Il est un code simple qui effectue une vérification sur chaque élément du tableau multidimensionnel k et si les trois éléments sont les mêmes et égale à 0, il affecte la valeur 1.

Existe-t-il un moyen de le rendre plus rapide? La matrice k a 1 444 000 éléments et cela prend trop de temps pour l'exécuter. Quelqu'un peut-il aider?

Merci

+1

Veuillez fournir un exemple * reproductible *. –

+0

ma matrice k est vraiment grande, mais imaginez juste qu'elle pourrait être définie comme suit 'k <-array (c (1,1,1,0,2,2,2,0,3,3,3,0), dim = c (2,2,3)) ' –

+0

Collez simplement' dput (head (k)) 'ou, si cela est encore trop grand, affinez les dimensions pour inclure' k [c (1,2), c (1,2), 1, c (1: 3)] '. – LAP

Répondre

2

Avec application, vous pouvez retourner tous vos 3 combinaisons comme vecteur numérique, puis vérifier votre condition spécifique:

# This creates an array with the same properties as yours 
    array <- array(data = sample(c(0, 1), 81, replace = TRUE, 
         prob = c(0.9, 0.1)), c(3, 3, 3, 3)) 

    # This loops over all vectors in the fourth dimension and returns a 
    # vector of ones if your condition is met 
    apply(array, MARGIN = c(1, 2, 3), FUN = function(x) { 
     if (sum(x) == 0 & length(unique(x)) == 1) 
     return(c(1, 1, 1)) 
     else 
     return(x) 
    }) 

Notez que l'argument MARGIN spécifie les dimensions sur lesquelles à boucle . Vous voulez les vecteurs de quatrième dimension, donc vous spécifiez c(1, 2, 3).

Si vous affectez ensuite ce tableau nouvellement créé à l'ancien, vous avez remplacé tous les vecteurs où la condition est remplie par les uns.

+2

Notez que 'sum (x) == 0' pourrait être' TRUE' si 'x' contient à la fois des valeurs négatives et positives, –

+0

Ouais je viens d'ajouter' length (unique (x)) == 1'. Merci. – Stan125

+0

La solution affichée a-t-elle fonctionné? Si c'est le cas, pensez à accepter la réponse en cliquant sur la coche.Ceci indique à la communauté plus large que vous avez trouvé une solution et donne une certaine réputation à la fois le répondeur et vous-même. Il n'y a aucune obligation de le faire. – Stan125

0

Vous devez d'abord utiliser la fonction de filtre deux fois (composée), puis la fonction apply (lapply?) Sur le tableau filtré. Peut-être que vous pouvez également réduire le tableau, car il semble que vous n'êtes pas très intéressé par la troisième dimension (toujours accéder au 1er élément). Vous devriez probablement faire un peu de lecture sur la programmation fonctionnelle R ici http://adv-r.had.co.nz/Functionals.html

Remarque Je ne suis pas un programmeur R, mais je suis assez familier avec la programmation fonctionnelle (Haskell etc) donc cela peut vous donner une idée. Cela pourrait être plus rapide, mais cela dépend un peu de la façon dont R est conçu (évaluation paresseuse ou désireuse, etc.).