sheet - r markdown the definitive guide pdf
En `knitr`, ¿cómo puedo comprobar si el resultado será PDF o Word? (4)
Me gustaría incluir contenido específico según el formato que se está creando.
En este ejemplo específico, mis tablas se ven terribles en la salida de
MS word
, pero geniales en
HTML
.
Me gustaría agregar alguna prueba para omitir la tabla dependiendo de la salida.
Aquí hay un pseudocódigo:
output.format <- opts_chunk$get("output")
if(output.format != "MS word"){
print(table1)
}
Estoy seguro de que esta no es la forma correcta de usar
opts_chunk
, pero este es el límite de mi comprensión de cómo funciona
knitr
debajo del capó.
¿Cuál sería la forma correcta de probar esto?
Respuesta corta
En la mayoría de los casos,
opts_knit$get("rmarkdown.pandoc.to")
entrega la información requerida.
De lo contrario, consulte
rmarkdown::all_output_formats(knitr::current_input())
y verifique si el valor de retorno contiene
word_document
:
if ("word_document" %in% rmarkdown::all_output_formats(knitr::current_input()) {
# Word output
}
Respuesta larga
Supongo que el documento fuente es RMD porque este es el formato de entrada habitual / más común para tejer en diferentes formatos de salida como MS Word, PDF y HTML.
En este caso,
knitr
opciones de
knitr
no se pueden usar para determinar el formato de salida final porque no importa desde la perspectiva de
knitr
: para todos los formatos de salida, el trabajo de
knitr
es tejer el archivo RMD de entrada en un archivo MD.
La conversión del archivo MD al formato de salida especificado en el encabezado YAML se realiza en la siguiente etapa, mediante
pandoc
.
Por lo tanto, no podemos usar la
opción de paquete
knitr::opts_knit$get("out.format")
para obtener información sobre el formato de salida final, pero en su lugar debemos analizar el encabezado YAML.
Hasta ahora en teoría.
La realidad es un poco diferente.
El botón "Knit PDF" / "Knit HTML" de
rmarkdown::render
llama a
rmarkdown::render
que a su vez llama
knit
.
Antes de que esto suceda,
render
establece
una
opción de paquete (¿no documentado?)
rmarkdown.pandoc.to
en el formato de salida real.
El valor será
html
,
latex
o
docx
respectivamente, dependiendo del formato de salida.
Por lo tanto, si (y solo si) se usa el botón "Knit PDF" / "Knit HTML" de
knitr::opts_knit$get("rmarkdown.pandoc.to")
,
knitr::opts_knit$get("rmarkdown.pandoc.to")
puede usarse para determinar el formato de salida.
Esto también se describe en
esta respuesta
y en
esa publicación de blog
.
El problema sigue sin resolverse para el caso de llamar a
knit
directamente porque entonces
rmarkdown.pandoc.to
no está configurado.
En este caso, podemos explotar la función (no
parse_yaml_front_matter
)
parse_yaml_front_matter
del paquete
rmarkdown
para analizar el encabezado YAML.
[
Actualización
: a partir de
rmarkdown
0.9.6, se ha agregado la función
all_output_formats
(gracias a
Bill Denney
por señalar esto).
Hace que la función personalizada desarrollada a continuación
rmarkdown::all_output_formats
obsoleta: para la producción, use
rmarkdown::all_output_formats
!
Dejo el resto de esta respuesta tal como está escrita originalmente con fines educativos.]
---
output: html_document
---
```{r}
knitr::opts_knit$get("out.format") # Not informative.
knitr::opts_knit$get("rmarkdown.pandoc.to") # Works only if knit() is called via render(), i.e. when using the button in RStudio.
rmarkdown:::parse_yaml_front_matter(
readLines(knitr::current_input())
)$output
```
El ejemplo anterior muestra el uso (lesness) de
opts_knit$get("rmarkdown.pandoc.to")
(
opts_knit$get("out.format")
), mientras que la línea que emplea
parse_yaml_front_matter
devuelve el formato especificado en el campo "salida" del encabezado YAML.
La entrada de
parse_yaml_front_matter
es el archivo fuente como vector de caracteres, tal como lo devuelve
readLines
.
Para determinar el nombre del archivo que se está tejiendo actualmente, se utiliza
current_input()
como se sugiere en
esta respuesta
.
Antes de que
parse_yaml_front_matter
se pueda usar en una instrucción
if
simple para implementar un comportamiento que esté condicionado al formato de salida, se requiere un pequeño refinamiento: la declaración que se muestra arriba puede devolver una lista si hay parámetros YAML adicionales para la salida como en este ejemplo:
---
output:
html_document:
keep_md: yes
---
La siguiente función auxiliar debería resolver este problema:
getOutputFormat <- function() {
output <- rmarkdown:::parse_yaml_front_matter(
readLines(knitr::current_input())
)$output
if (is.list(output)){
return(names(output)[1])
} else {
return(output[1])
}
}
Se puede usar en construcciones como
if(getOutputFormat() == ''html_document'') {
# do something
}
Tenga en cuenta que
getOutputFormat
usa solo el primer formato de salida especificado, por lo que con el siguiente encabezado solo se devuelve
html_document
:
---
output:
html_document: default
pdf_document:
keep_tex: yes
---
Sin embargo, esto no es muy restrictivo.
Cuando se usa el botón "Knit HTML" / "Knit PDF" de RStudio (junto con el menú desplegable al lado para seleccionar el tipo de salida), RStudio reorganiza el encabezado YAML de modo que el formato de salida seleccionado sea el primer formato de la lista.
Los formatos de salida múltiples son (AFAIK) solo relevantes cuando se usa
rmarkdown::render
with
output_format = "all"
.
Y: En ambos casos, se puede usar
rmarkdown.pandoc.to
, que de todos modos es más fácil.
Desde
knitr
1.18, puede usar las dos funciones
knitr::is_html_output()
y
knitr::is_latex_output()
Solo quiero agregar un poco de aclaración aquí, ya que a menudo renderizo el mismo archivo Rmarkdown (* .Rmd) en múltiples formatos (* .html, * .pdf, * .docx), así que en lugar de querer saber si el formato de el interés se encuentra entre los especificados en el tema principal yaml (es decir,
"word_document" %in% rmarkdown::all_output_formats(knitr::current_input()
), quiero saber qué formato se está procesando actualmente. Para ello, puede:
-
Obtenga el primer elemento de los formatos enumerados en primer
rmarkdown::all_output_formats(knitr::current_input()[1]
:rmarkdown::all_output_formats(knitr::current_input()[1]
; o -
Obtener el nombre del formato de salida predeterminado:
rmarkdown::default_output_format(knitr::current_input())$name
Por ejemplo...
---
title: "check format"
output:
html_document: default
pdf_document: default
word_document: default
---
```{r}
rmarkdown::all_output_formats(knitr::current_input())[1]
```
```{r}
rmarkdown::default_output_format(knitr::current_input())$name
```
```{r}
fmt <- rmarkdown::default_output_format(knitr::current_input())$name
if (fmt == "pdf_document"){
#...
}
if (fmt == "word_document"){
#...
}
```
Un punto adicional: las respuestas anteriores no funcionan para un
html_notebook
, ya que el código se ejecuta directamente allí y
knitr::current_input()
no responde.
Si conoce el nombre del documento, puede llamar a
all_output_formats
como se
all_output_formats
arriba, especificando el nombre explícitamente.
No sé si hay otra forma de hacer esto.