Equivalente de "lanzamiento" en R

140

¿Cómo se "arroja" un error en R? Tengo una función que toma un marco de datos y algunos nombres de columna y hace cosas con ellos. Si las columnas no existen, quiero que la función se detenga y que detenga todas las funciones dependiendo de ella.

He mirado recovery browsey tracebackpero, bueno, parecían estar cerca pero no era lo que estaba buscando.

Forkandwait
fuente
2
Correcto, recovery, browser y traceback son para depuración, mientras que los sistemas try / catch son para manejar errores en el código de producción.
Harlan
20
Me encanta cuando los que hacen preguntas usan el nombre de la función que buscan varias veces en una pregunta;)
hadley
Creo que hay una razón por la cual esta pregunta tiene más votos a favor que la respuesta principal. Aunque esta otra pregunta está técnicamente fuera de tema, es ese tipo de resumen excelentemente ajustado de un tema desconocido por el que Stack Overflow es famoso.
Josiah Yoder

Respuestas:

113

Ver help(tryCatch):

Las condiciones se señalan con ' signalCondition'. Además, las funciones
' stop' y ' warning' se han modificado para aceptar también
argumentos de condición.

y luego en 'Ver también':

' stop' y ' warning' condiciones de señal, y ' try' es esencialmente una versión simplificada de ' tryCatch'.

por lo que es probable que desee stop.

Dirk Eddelbuettel
fuente
24
Eso funciona perfectamente R es tan extraño, sin culpa propia: fue diseñado mucho antes de que resolvamos un buen diseño de lenguaje interpretado.
forkandwait
55
Según los autores, fue fuertemente influenciado por Scheme, que es antiguo y bueno. R es 'lispy' pero con estructuras de datos originales. Las partes "interesantes" en R probablemente estén relacionadas con que muchas convenciones difieren de otros lenguajes, especialmente la familia del lenguaje C, que también es sintácticamente cercana. Supongo que porque el lenguaje fue desarrollado por un grupo de estadísticos que necesitaban una buena herramienta, en lugar de que los desarrolladores necesitaran una buena herramienta. Solo el hecho de que el 'punto' es solo un personaje tardó mucho en
asimilarse
55
Algunos ejemplos básicos aquí serían geniales, no solo tienen citas. Aquí stackoverflow.com/a/23917007/54964
Léo Léopold Hertz 준영
Llegué a esta pregunta cuando buscaba cómo volver a lanzar un error en R con un mensaje de error más sano, pero manteniendo intacta la traza (como en, ejecutas traceback()después del error para ver qué salió mal). Usar stopen errorargumento de tryCatchdesordenará el rastro. Sin embargo, el finallyargumento permitirá lanzar un mensaje adicional y mantendrá útil la traza. No es exactamente sobre el tema, pero creo que es lo suficientemente importante como para justificar algunas desventajas y una amenaza de moderación que arroja este comentario por la ventana. :-)
Mali Remorker
48

Ejemplo simple:

f <- function(a, b){ 

    if (a == 0){ 
            stop("error message")
    }
 }
Christian Herrera Jiménez
fuente
Aquí stackoverflow.com/a/23917007/54964 para las variables en los mensajes de error.
Léo Léopold Hertz 준영
8

Más allá de las funciones básicas que Dirk menciona:

El paquete R.oo tiene una funcionalidad adicional de manejo de excepciones, incluida una función throw () que es muy útil. Puede detectar excepciones con las funciones habituales try o trycatch:

> try(throw("Division by zero.")); print("It's ok!");
Error: [2009-10-22 10:24:07] Exception: Division by zero.
[1] "It's ok!"

Puede leer más sobre esto aquí: http://www1.maths.lth.se/help/R/R.oo/

Shane
fuente
8
Jeje. R no es lo suficientemente funky sin OO? Perdón por ser flip, y definitivamente gracias por la interesante respuesta, pero iré con el viejo stop () anterior.
forkandwait
1
Hay incluso más OO ahora. :)
Iterator
3
@ws. ¿Qué tiene de funky R? plottraza una función, try stop warntodo funciona como es de esperar, y casi todo lo que quiero hacer es una línea.
isomorfismos
44
A menudo, el "poder de una línea" no es una buena métrica para un idioma. Para muchos de nosotros, el código legible y comprensible supera a menos líneas. De hecho, mucho es ininteligible para mí porque soy un principiante y trato de calibrar las expectativas en consecuencia. Pero otros lenguajes hacen que sea bastante intuitivo pasar de 0 a hacer cosas. R también parece haber desarrollado una cultura de frases ingeniosas y difíciles de leer. Yo abogaría por una cultura de código máximo similar al inglés, que a menudo también podría ser una línea, como Ruby.
Philip
6

En realidad la función stopifnot es muy conveniente para implementar controles de cordura en su código. Toma varias expresiones lógicas y devuelve un error si alguna de ellas se evalúa como falsa.

Ejemplo: para verificar si la columna 'c' existe en el marco de datos 'df':

df <- data.frame(a = numeric(), b = numeric())
stopifnot(!is.null(df$c))

Esto arrojará el siguiente error:

Error: !is.null(df$c) is not TRUE
Chris
fuente
Suena como Python assert(...)...
Josiah Yoder
1

Puede verificar si la columna existe y hacer lo que quiera.
Supongamos una columna con data.framenombre df1y comprobando si col1existe:

if(! any(grepl('^col1$',colnames(df1)))) stop("nonexistent column")

o

if(! any(grepl('^col1$',colnames(df1)))) return(-1)

Por ejemplo

xm1
fuente