Tenho um programa que faz algumas análises de dados e tem algumas centenas de linhas.
Bem no início do programa, quero fazer algum controle de qualidade e, se não houver dados suficientes, quero que o programa seja encerrado e retorne ao console R. Caso contrário, quero que o resto do código seja executado.
Eu tentei break
, browser
e quit
e nenhum deles para a execução do resto do programa (e quit
para a execução, bem como fechei completamente o R, o que não é algo que eu quero que aconteça). Meu último recurso é criar uma if-else
declaração como a seguir:
if(n < 500){}
else{*insert rest of program here*}
mas isso parece uma prática de codificação ruim. Estou esquecendo de algo?
quit
certamente interrompe a execução do resto do programa. Forneça um exemplo reproduzível .quit
sai de todo o R, mas quero voltar ao console do R porque o programa precisa permanecer aberto para meus propósitos.Respostas:
Você pode usar a
stopifnot()
função se quiser que o programa produza um erro:foo <- function(x) { stopifnot(x > 500) # rest of program }
fonte
foo
deve ser chamada no início do script e conter outro controle de validações ...stopifnot
é útil, mas uma resposta criada usandoif(x < 500) { stop("Not enough observations in 'x': n < 500")}
pode ser preferível. Além disso, se isso for algo para um trabalho em lote, lidar com o problema sem gerar um erro é útil.quit
(veja a pergunta!) Eu nem sequer pensarstop
destopifnot
é a melhor maneira de lidar com isso;stop
gera um erro, todo o script será abortado. Emborastopifnot
(oustop
) pareça ser a resposta preferida pela OP, escrever uma função para sair de forma limpa, sem erros, é mais benéfico em uma ampla gama de situações. Tendo escrito muitos scripts de longa execução para grandes trabalhos de análise de dados, nada é mais irritante do que funções que geram erros em vez de lidar com o problema e retornar de forma limpa. Mas claramente não sei do que estou falando ...stop("my message")
sou impresso no terminalError: "my message" Execution halted
. Portanto, isso mostra uma saída de mensagem de erro, mas você está dizendo que não "lança" um erro? (ou seja, ele não interromperá uma tarefa em lote que foi definida para abortar se qualquer um dos scripts que ele chama lançar erros). Obrigado! (No momento estou chamando o script com Rscript)Não é bonito, mas aqui está uma maneira de implementar um
exit()
comando em R que funcione para mim.exit <- function() { .Internal(.invokeRestart(list(NULL, NULL), NULL)) } print("this is the last message") exit() print("you should not see this")
Apenas testado levemente, mas quando executo isso, vejo
this is the last message
e, em seguida, o script é abortado sem nenhuma mensagem de erro.fonte
R CMD CHECK
..invokeRestart
que, por sua vez, parece precisar do.Internal
.exit <- function() { invokeRestart("abort") }
Reverta sua construção if-else:
if(n >= 500) { # do stuff } # no need for else
fonte
Edit: Parece que o OP está executando um script longo, nesse caso, basta quebrar a parte do script após o controle de qualidade com
if (n >= 500) { .... long running code here }
Se estiver saindo de uma função , você provavelmente só desejará
return()
, explícita ou implicitamente.Por exemplo, um retorno duplo explícito
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
Por
return()
estar implícito, quero dizer que a última linha é como se você tivesse feitoreturn(xx)
, mas é um pouco mais eficiente deixar de fora a chamada parareturn()
.Alguns consideram o uso de várias devoluções em um estilo ruim; em funções longas, manter o controle de onde a função sai pode se tornar difícil ou sujeito a erros. Portanto, uma alternativa é ter um único ponto de retorno, mas alterar o objeto de retorno usando a
if () else ()
cláusula. Essa modificaçãofoo()
seriafoo <- 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
fonte
myFun(arg1, arg2, arg3)
etc. É apenas uma maneira muito melhor de organizar as coisas.Talvez você apenas queira parar de executar um script longo em algum momento. ie. como você deseja codificar permanentemente um exit () em C ou Python.
print("this is the last message") stop() print("you should not see this")
fonte
Error in eval(expr, envir, enclos) :
.stop()
porexit()
ouplease.stop.now()
, o script também será interrompido (apenas as mensagens de erro são obviamente diferentes).stop()
comando pode ajudar a distinguir esse "erro" de outras mensagens. Por exemplo:stop("Manual break inserted here")
pode ser mais informativo do questop()
sozinho.Esta é uma questão antiga, mas ainda não há uma solução limpa. Isso provavelmente não está respondendo a esta pergunta específica, mas aqueles que procuram respostas sobre 'como sair de um script R normalmente' provavelmente chegarão aqui. Parece que os desenvolvedores do R se esqueceram de implementar uma função exit (). De qualquer forma, o truque que encontrei é:
continue <- TRUE tryCatch({ # You do something here that needs to exit gracefully without error. ... # We now say bye-bye stop("exit") }, error = function(e) { if (e$message != "exit") { # Your error message goes here. E.g. stop(e) } continue <<-FALSE }) if (continue) { # Your code continues here ... } cat("done.\n")
Basicamente, você usa um sinalizador para indicar a continuação ou não de um bloco de código especificado. Em seguida, você usa a
stop()
função para passar uma mensagem personalizada para o manipulador de erros de umatryCatch()
função. Se o manipulador de erros receber sua mensagem para sair normalmente, ele simplesmente ignora o erro e define o sinalizador de continuação comoFALSE
.fonte
Você pode usar a
pskill
função doR
pacote "ferramentas" para interromper o processo atual e retornar ao console. Concretamente, tenho a seguinte função definida em um arquivo de inicialização que forneço no início de cada script. Você também pode copiá-lo diretamente no início do seu código. Em seguida, insirahalt()
em qualquer ponto do código para interromper a execução do script imediatamente. Esta função funciona bem no GNU / Linux e, a julgar pelaR
documentação, também deve funcionar no Windows (mas não verifiquei).# halt: interrupts the current R process; a short iddle time prevents R from # outputting further results before the SIGINT (= Ctrl-C) signal is received halt <- function(hint = "Process stopped.\n") { writeLines(hint) require(tools, quietly = TRUE) processId <- Sys.getpid() pskill(processId, SIGINT) iddleTime <- 1.00 Sys.sleep(iddleTime) }
fonte
Aqui:
if(n < 500) { # quit() # or # stop("this is some message") } else { *insert rest of program here* }
Ambos
quit()
estop(message)
sairão do seu script. Se você estiver fornecendo seu script a partir do prompt de comando R,quit()
sairá do R também.fonte
stop()
e OP já indicou nos comentários que eles não queremquit()
...