Quebrando o loop quando "avisos ()" aparecem em R

103

Estou tendo um problema: estou executando um loop para processar vários arquivos. Minhas matrizes são enormes e, portanto, geralmente fico sem memória se não tomar cuidado.

Existe uma maneira de sair de um loop se algum aviso for criado? Ele apenas continua executando o loop e relata que falhou muito mais tarde ... irritante. Alguma idéia, oh sábio stackoverflow-ers ?!

mmann1123
fonte

Respostas:

150

Você pode transformar avisos em erros com:

options(warn=2)

Ao contrário dos avisos, os erros interromperão o loop. Bem, R também informará a você que esses erros específicos foram convertidos de avisos.

j <- function() {
    for (i in 1:3) {
        cat(i, "\n")
        as.numeric(c("1", "NA"))
}}

# warn = 0 (default) -- warnings as warnings!
j()
# 1 
# 2 
# 3 
# Warning messages:
# 1: NAs introduced by coercion 
# 2: NAs introduced by coercion 
# 3: NAs introduced by coercion 

# warn = 2 -- warnings as errors
options(warn=2)
j()
# 1 
# Error: (converted from warning) NAs introduced by coercion
Josh O'Brien
fonte
23
Depois, use options(warn=1) para restaurar a configuração padrão.
Alex Holcombe
25
O valor padrão é 0. Portanto, para restaurar as configurações de fábrica, use options("warn"=0).
Dirk Eddelbuettel
A melhor maneira de fazer a redefinição das opções em R é 1) op=options(warn=2), 2) fazer o options(op)que deseja e, em seguida, 3) redefinir com , o que o leva de volta warn=0neste caso.
mbiron
44

R permite que você defina um manipulador de condição

x <- tryCatch({
    warning("oops")
}, warning=function(w) {
    ## do something about the warning, maybe return 'NA'
    message("handling warning: ", conditionMessage(w))
    NA
})

o que resulta em

handling warning: oops
> x
[1] NA

A execução continua após tryCatch; você pode decidir encerrar convertendo seu aviso em um erro

x <- tryCatch({
    warning("oops")
}, warning=function(w) {
    stop("converted from warning: ", conditionMessage(w))
})

ou lidar com a condição normalmente (avaliação contínua após a chamada de aviso)

withCallingHandlers({
    warning("oops")
    1
}, warning=function(w) {
    message("handled warning: ", conditionMessage(w))
    invokeRestart("muffleWarning")
})

quais impressões

handled warning: oops
[1] 1
Martin Morgan
fonte
+1 - Excelente. Pensei em mencionar essa opção, mas não poderia ter montado um tutorial tão curto, mas fofo.
Josh O'Brien
ter uma demonstração com um simpático forseria ainda melhor :)
JelenaČuklina
28

Defina a warnopção global :

options(warn=1)  # print warnings as they occur
options(warn=2)  # treat warnings as errors

Observe que um "aviso" não é um "erro". Os loops não terminam para avisos (a menos que options(warn=2)).

Joshua Ulrich
fonte