tutorial false examples don chunk r markdown knitr

false - r markdown tutorial pdf



¿Cómo solicitar una salida anticipada al tejer un documento Rmd? (2)

Supongamos que tiene un documento de reducción de valor R que no se procesará de forma limpia.

Sé que puede establecer el error opción knitr chunk en TRUE para solicitar que la evaluación continúe, incluso en presencia de errores. Puede hacer esto para un fragmento individual a través de error = TRUE o de una manera más global a través de knitr::opts_chunk$set(error = TRUE) .

Pero a veces hay errores que aún son fatales para el proceso de tejido. Recientemente he encontrado dos ejemplos: tratar de unlink() el directorio de trabajo actual (¡oops!) Y llamar a rstudioapi::getVersion() desde el código en línea R cuando RStudio no está disponible. ¿Hay una descripción general de este tipo de errores, es decir, los que están más allá del alcance de error = TRUE ? ¿Hay alguna forma de tolerar errores en el código R en línea frente a los fragmentos?

Además, ¿hay más formas oficiales de detener el tejido temprano o automatizar la depuración en esta situación?


En mi humilde opinión, la dificultad de depurar un documento Rmd es una advertencia de que algo está mal. Tengo una regla de oro: hacer el trabajo pesado fuera del Rmd. Hacer renderizado dentro del Rmd, y solo renderizar. Eso mantiene el código Rmd simple.

Mis grandes programas de R se parecen a esto.

data <- loadData() analytics <- doAnalytics(data) rmarkdown::render("theDoc.Rmd", envir=analytics)

(Aquí, doAnalytics devuelve una lista o entorno. Esa lista o entorno se pasa al documento Rmd a través del parámetro envir , lo que hace que los resultados de los cálculos analíticos estén disponibles dentro del documento).

La función doAnalytics hace los cálculos complicados. Puedo depurarlo usando las herramientas normales y puedo verificar fácilmente su salida. Cuando llamo a rmarkdown :: render , sé que las cosas difíciles están funcionando correctamente. El código Rmd es simplemente "imprimir esto" y "formatear eso", fácil de depurar.

Esta división de responsabilidad me ha servido bien, y puedo recomendarlo. Especialmente comparado con la tarea alucinante de depurar cálculos complicados enterrados dentro de un documento renderizado dinámicamente.


Para salir temprano del proceso de tejido, puede usar la función knitr::knit_exit() en cualquier parte del documento de origen (en un fragmento de código o expresión en línea). Una vez que se llama a knit_exit() , knitr ignorará el resto del documento y escribirá los resultados que ha recopilado hasta el momento.

No hay forma de tolerar errores en el código R en línea en este momento. Debe asegurarse de que el código R en línea siempre se ejecuta sin errores 1 . Si se producen errores, debería ver el rango de líneas que produjo el error del registro knitr en la consola, del formulario Quitting from lines x1-x2 (filename.Rmd) . Luego puede ir al archivo filename.Rmd y ver qué hay de malo en las líneas de x1 a x2 . Lo mismo se aplica a los fragmentos de código con el error = FALSE opción de fragmento error = FALSE .

Más allá de los tipos de errores mencionados anteriormente, puede ser difícil encontrar la fuente del problema. Por ejemplo, cuando unlink() involuntariamente unlink() el directorio actual, no debe detener el proceso de tejido, porque el unlink() tuvo éxito de todos modos. Es posible que tenga problemas después del proceso de tejido, por ejemplo, LaTeX / HTML no puede encontrar los archivos de figuras de salida. En este caso, puede intentar aplicar knit_exit() a todos los fragmentos de código del documento uno por uno. Una forma de lograr esto es configurar un gancho de trozo para ejecutar knit_exit() después de un trozo determinado. A continuación se muestra un ejemplo del uso de la búsqueda lineal (en su lugar, puede mejorarla utilizando la bisección):

#'' Render an input document chunk by chunk until an error occurs #'' #'' @param input the input filename (an Rmd file in this example) #'' @param compile a function to compile the input file, e.g. knitr::knit, or #'' rmarkdown::render knit_debug = function(input, compile = knitr::knit) { library(knitr) lines = readLines(input) chunk = grep(all_patterns$md$chunk.begin, lines) # line number of chunk headers knit_hooks$set(debug = function(before) { if (!before) { chunk_current <<- chunk_current + 1 if (chunk_current >= chunk_num) knit_exit() } }) opts_chunk$set(debug = TRUE) # try to exit after the i-th chunk and see which chunk introduced the error for (chunk_num in seq_along(chunk)) { chunk_current = 0 # a chunk counter, incremented after each chunk res = try(compile(input)) if (inherits(res, ''try-error'')) { message(''The first error came from line '', chunk[chunk_num]) break } } }

  1. Esto es por diseño. Creo que es una buena idea tener error = TRUE para fragmentos de código, ya que a veces queremos mostrar errores, por ejemplo, con fines de enseñanza. Sin embargo, si también permito errores para el código en línea, los autores pueden no reconocer los errores fatales en el código en línea. El código en línea normalmente se usa para incrustar valores en línea, y no creo que tenga mucho sentido si un valor en línea es un error. Imagine una oración en un informe como The P-value of my test is ERROR , y si Knitr no señaló el error, los autores deberán leer el informe con mucha atención para detectar este problema. Creo que es una mala idea tener que confiar en los ojos humanos para encontrar tales errores.