2015-12-07 2 views
1

J'essaye de programmer un script qui saute les deux prochaines itérations s'il trouve une correspondance de données. Pour une itération, je pourrais utiliser la commande "next", mais ça ne marche pas pour sauter plusieurs itérations.Sauter plusieurs itérations de boucle

Voici mon script.

rowsToDelete<-c() 

for(o in 1:nrow(data)){ 
    if(data$reactionTime[o]>2000||data$V8[o]<9999){ 

     rowsToDelete<-rbind(rowsToDelete,TRUE,TRUE,TRUE) 
     o<-o+2 

    } 
    else{ 
     rowsToDelete<-rbind(rowsToDelete,FALSE) 
    } 
} 

Je viens de figure ne peux pas comprendre pourquoi la partie avec o<-o+2 dans la boucle si ne saute pas les deux prochaines itérations, il agrandit juste la quantité d'itérations de 13000-14430 (La différence est la quantité de mauvais cas mes temps de données 2).

+2

Pouvez-vous décrire exactement ce que vous essayez de faire? il peut y avoir une façon plus simple de le faire. (par exemple, obtenez quelles lignes remplissent les conditions et en déduire les lignes à supprimer). (nb: comme 'rowsToDelete' est un vecteur, utilisez' c (rowsToDelete, ...) 'au lieu de' rbind') – Cath

Répondre

1

Je suggère de gérer le compteur vous avec repeat et break comme ceci:

rowsToDelete<-c() 
o<-1 
repeat{ 
    if(data$reactionTime[o]>2000||data$V8[o]<9999){ 
    rowsToDelete<-rbind(rowsToDelete,TRUE,TRUE,TRUE) 
    o<-o+2 
    } 
    else{ 
    rowsToDelete<-rbind(rowsToDelete,FALSE) 
    o<-o+1 
    } 

    if (o == nrow(data)) break 
} 
+2

Je suggérerais littéralement * n'importe quelle autre solution. Voici comment programmer en C, pas en R. –

1

R fonctionne différemment, à deux égards.

  1. for boucles ne fonctionnent pas comme ça - vous ne pouvez pas modifier la variable de boucle, comme vous l'avez remarqué. De plus, vous ne faites généralement pas d'itération sur les index, mais plutôt sur les éléments directement.

  2. Pour sélectionner ou supprimer des objets spécifiques d'un vecteur/matrix/data.frame, il vous suffit de sélectionner ces éléments via un index numérique ou logique. Votre code est déjà en cours dans ce sens, mais vous construisez cet indice (rowsToDelete) itérativement plutôt que dans un aller

En corollaire (2), ne créent pas des vecteurs ou des listes dans une rangée par concaténation itérative - c'est vraiment, vraiment lent.

est ici d'une manière différente, en utilisant les expressions vectorisées de R:

rowsToDelete = data$reactionTime > 2000 | data$V8 < 9999 

Notez que je l'ai remplacé || avec le vectorisée |. Cela renvoie un vecteur dont les éléments sont TRUE lorsque la condition est remplie. Ensuite, nous devons étendre ce vecteur logique tel que, si un élément à l'index i est TRUE, les indices à i +1 et i 2 seront également TRUE:

rowsToDelete = rowsToDelete | c(FALSE, rowsToDelete) | c(FALSE, FALSE, rowsToDelete) 

Cette Il décale simplement le vecteur d'un élément, puis de deux éléments, et les combine via un «ou» logique. Cependant, notez que cela entraîne des avertissements, puisque maintenant les vecteurs que nous combinons via "ou" n'ont plus la même longueur. En général, c'est une bonne idée de tenir compte de cet avertissement. Nous pouvons l'éviter ici en utilisant une petite fonction d'assistance:

shift = function (x, element = FALSE) c(element, x[-length(x)]) 

rowsToDelete = data$reactionTime > 2000 | data$V8 < 9999 
rowsToDelete = rowsToDelete | shift(rowsToDelete) | shift(shift(rowsToDelete))