112 votes

break/exit script

J'ai un programme qui fait de l'analyse de données et qui fait quelques centaines de lignes.

Très tôt dans le programme, je veux faire un contrôle de qualité et s'il n'y a pas assez de données, je veux que le programme se termine et retourne à la console R. Sinon, je veux que le reste du code s'exécute.

J'ai essayé break , browser et quit et aucune d'entre elles n'arrête l'exécution du reste du programme (et quit arrête l'exécution ainsi que l'abandon complet de R, ce qui n'est pas quelque chose que je veux voir se produire). Mon dernier recours est de créer un if-else comme ci-dessous :

 if(n < 500){}
 else{*insert rest of program here*}

mais cela semble être une mauvaise pratique de codage. Est-ce que quelque chose m'échappe ?

76voto

Michael Malick Points 1718

Vous pourriez utiliser le stopifnot() si vous voulez que le programme produise une erreur :

foo <- function(x) {
    stopifnot(x > 500)
    # rest of program
}

20voto

netskink Points 81

Peut-être voulez-vous simplement arrêter l'exécution d'un long script à un moment donné, comme si vous vouliez coder en dur un exit() en C ou en Python.

print("this is the last message")
stop()
print("you should not see this")

20voto

jochen Points 570

Édité. Merci à @Droplet, qui a trouvé un moyen de faire fonctionner ce système sans l'option .Internal() : Voici une façon d'implémenter un exit() dans R.

exit <- function() { invokeRestart("abort") }    

print("this is the last message")
exit()
print("you should not see this")

Je ne l'ai testé que légèrement, mais quand je l'exécute, je vois this is the last message et ensuite le script s'arrête sans aucun message d'erreur.

Voici la version la plus moche de ma réponse originale.

exit <- function() {
  .Internal(.invokeRestart(list(NULL, NULL), NULL))
}

15voto

Thomas Points 14021

Inversez votre construction if-else :

if(n >= 500) {
  # do stuff
}
# no need for else

10voto

Gavin Simpson Points 72349

Edit : Il semble que le PO exécute un long script, dans ce cas il faut seulement envelopper la partie du script. après le contrôle de la qualité avec

if (n >= 500) {

.... long running code here

}

Si vous vous échappez d'un fonction vous voudrez probablement juste return() soit explicitement ou implicitement.

Par exemple, un double retour explicite

foo <- function(x) {
  if(x < 10) {
    return(NA)
  } else {
    xx <- seq_len(x)
    xx <- cumsum(xx)
  }
  xx ## return(xx) is implied here
}

> foo(5)
[1] 0
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

Par return() étant implicite, je veux dire que la dernière ligne est comme si vous aviez fait return(xx) mais il est légèrement plus efficace d'omettre l'appel à return() .

Certains considèrent que l'utilisation de retours multiples est une erreur de style ; dans les fonctions longues, il peut être difficile de savoir où la fonction se termine ou de commettre des erreurs. Une alternative est donc d'avoir un seul point de retour, mais de changer l'objet de retour en utilisant la fonction if () else () clause. Une telle modification de foo() serait

foo <- function(x) {
  ## out is NA or cumsum(xx) depending on x
  out <- if(x < 10) {
    NA
  } else {
    xx <- seq_len(x)
    cumsum(xx)
  }
  out ## return(out) is implied here
}

> foo(5)
[1] NA
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X