¿Cuáles son los efectos secundarios (posiblemente no deseados) de utilizar knit()
/ knit2pdf()
lugar del botón “Comstackr PDF” 1 en RStudio?
La mayoría de los usuarios de knitr
parecen escribir sus documentos en RStudio y comstackr los documentos usando el botón “Comstackr PDF” / “Knit HTML”. Esto funciona sin problemas la mayor parte del tiempo, pero de vez en cuando hay requisitos especiales que no se pueden lograr con el botón de comstackción. En estos casos, la solución suele ser llamar a knit()
/ knit2pdf()
/ rmarkdown::render()
(o funciones similares) directamente.
Algunos ejemplos:
El uso de knit2pdf()
lugar del botón “Comstackr PDF” generalmente ofrece una solución simple para tales preguntas. Sin embargo, esto tiene un precio: existe la diferencia fundamental de que “Comstackr PDF” procesa el documento en un proceso y entorno separados, mientras que knit2pdf()
y sus amigos no lo hacen.
Esto tiene implicaciones y el problema es que no todas estas implicaciones son obvias. Tome el hecho de que knit()
utiliza objetos del entorno global (mientras que “Comstackr PDF” no) como ejemplo. Esto podría ser obvio y el comportamiento deseado en casos como el segundo ejemplo anterior, pero es una consecuencia inesperada cuando se usa knit()
para superar problemas como en los ejemplos 1 y 3.
Además, hay diferencias más sutiles:
Cada vez que leo / escribo los consejos para usar knit2pdf()
lugar de “Comstackr PDF”, pienso “correcto, pero el usuario debe entender las consecuencias …” .
Por lo tanto, la pregunta aquí es:
¿Cuáles son los efectos secundarios (posiblemente no deseados) de utilizar
knit()
/knit2pdf()
lugar del botón “Comstackr PDF” en RStudio?
Si hubo una respuesta integral (¿wiki comunitario?) A esta pregunta, podría vincularse en futuras respuestas que sugieran utilizar knit2pdf()
.
Hay docenas de preguntas relacionadas a esta. Sin embargo, proponen solo código para (más o menos) reproducir el comportamiento del botón de RStudio o explican lo que “básicamente” sucede sin mencionar los posibles inconvenientes. Otros parecen ser preguntas muy similares, pero resultan ser un caso (muy) especial. Algunos ejemplos:
Sys.sleep(30)
sugerido ni el registro “Compile PDF” son perspicaces (ambos consejos apuntan a lo mismo). Creo que esta pregunta planteó muchos de los problemas que deberían ser parte de una respuesta. Sin embargo, puede haber muchos más aspectos que desconozco y que son la razón por la cual soy reacio a auto-responder esta pregunta (aunque podría intentarlo si nadie responde).
Probablemente, una respuesta debe cubrir tres puntos principales:
knit()
utiliza objetos del entorno de llamada (por defecto: envir = parent.frame()
) y las implicaciones para la reproducibilidad. Traté de abordar el problema de evitar que knit()
use objetos del exterior del documento en esta respuesta (segundo punto). No estoy seguro de la perspectiva correcta sobre el tema. Creo que ambas cosas: “¿Qué sucede cuando pulso ‘Comstackr PDF’ + implicaciones”, así como “Lo que sucede cuando uso knit()
+ implicaciones” es un buen enfoque para abordar la cuestión.
1 Lo mismo se aplica al botón “Knit HTML” cuando se escriben documentos RMD.
Antes que nada, creo que esta pregunta es más fácil de responder si limita el scope al botón “Comstackr PDF”, porque el botón “Knit HTML” es una historia diferente. “Comstackr PDF” es solo para documentos Rnw (R + LaTeX, o piensa en Sweave).
Responderé a tu pregunta siguiendo los tres puntos que sugeriste:
Actualmente RStudio siempre lanza una nueva sesión R para comstackr documentos Rnw, y primero cambia el directorio de trabajo al directorio del archivo Rnw. Puedes imaginar el proceso como un script de shell como este:
cd path/to/your-Rnw-directory Rscript -e "library(knitr); knit('your.Rnw')" pdflatex your.tex
Tenga en cuenta que el paquete knitr siempre está adjunto, y pdflatex
podría ser otros motores LaTeX (según las configuraciones de RStudio para documentos Sweave, por ejemplo, xelatex
). Si desea replicarlo en su sesión R actual, puede reescribir el script en R:
owd = setwd("path/to/your-Rnw-directory") system2("Rscript", c("-e", shQuote("library(knitr); knit('your.Rnw')")) system2("pdflatex", "your.tex") setwd(owd)
que no es tan simple como knitr::knit('path/to/your.Rnw')
, en cuyo caso el directorio de trabajo no se cambia automáticamente, y todo se ejecuta en la sesión R actual (en el globalenv()
de forma predeterminada )
Como el documento Rnw siempre se comstack en una nueva sesión R, no usará ningún objeto en su sesión R actual. Esto es difícil de replicar solo a través del argumento de knitr::knit()
de knitr::knit()
en la sesión R actual. En particular, no puede usar knitr::knit(envir = new.env())
porque aunque new.env()
es un entorno nuevo, tiene un entorno principal predeterminado parent.frame()
, que suele ser globalenv()
; tampoco puede usar knitr::knit(envir = emptyenv())
, porque es “demasiado limpio”, y tendrá problemas con los objetos incluso en el paquete base R. La única manera confiable de replicar lo que hace el botón “Comstackr PDF” es lo que dije en 1: system2("Rscript", c("-e", shQuote("library(knitr); knit('your.Rnw')"))
, en cuyo caso knit()
usa el globalenv()
de una nueva sesión R.
No estoy del todo seguro de lo que RStudio hace por la opción de repos
. Probablemente establezca automáticamente esta opción entre bastidores si no está configurada. Creo que este es un problema relativamente menor. Puede configurarlo en su .Rprofile
, y creo que RStudio debe respetar la configuración del espejo CRAN.
Los usuarios siempre han preguntado por qué el documento Rnw (o los documentos de R Markdown) no se comstackn en la sesión R actual. Para nosotros, básicamente se reduce a cuál de las siguientes consecuencias es más sorprendente o no deseada:
Para resumir, creo:
Hacer punto en una nueva sesión R es mejor para reproducibilidad;
Hacer punto en la sesión R actual es a veces más conveniente (por ejemplo, intenta tejer con diferentes objetos temporales R en la sesión actual). A veces también tiene que tejer en la sesión R actual, especialmente cuando está generando informes PDF programáticamente, por ejemplo, usa un bucle (for) para generar una serie de informes. No hay forma de que pueda lograr esto solo a través del botón “Comstackr PDF” (el botón es principalmente solo para un único documento Rnw).
Por cierto, creo que lo que dije arriba también se puede aplicar a los botones HTML Knit o Knit, pero la función subyacente es rmarkdown::render()
lugar de knitr::knit()
.