the - R knitr: ¿Posible modificar programáticamente las etiquetas de fragmentos?
r markdown tutorial pdf (2)
Para cualquier otra persona que se encuentre con esta publicación, quería señalar que @Yihui ha proporcionado una solución formal a esta pregunta en knitr 1.0 con la introducción de la función knit_expand()
. Funciona muy bien y realmente ha simplificado mi flujo de trabajo.
Por ejemplo, a continuación se procesará el script de plantilla a continuación para cada nivel de mtcars$cyl
, reemplazando cada vez todas las instancias de {{ncyl}}
(en la plantilla) con su valor actual:
# My report
```{r}
data(mtcars)
cyl.levels <- unique(mtcars$cyl)
```
## Generate report for each level of cylinder variable
```{r, include=FALSE}
src <- lapply(cyl.levels, function(ncyl) knit_expand(file = "template.Rmd"))
```
`r knit(text = unlist(src))`
Modelo:
```{r, results=''asis''}
cat("### {{ncyl}} cylinders")
```
```{r mpg-histogram-{{ncyl}}cyl}
hist(mtcars$mpg[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
```{r weight-histogam-{{ncyl}}cyl}
hist(mtcars$wt[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
Estoy intentando usar knitr para generar un informe que realice el mismo conjunto de análisis en diferentes subconjuntos de un conjunto de datos. El proyecto contiene dos archivos Rmd: el primer archivo es un documento maestro que configura el espacio de trabajo y el documento; el segundo archivo solo contiene fragmentos que realizan los análisis y genera figuras asociadas.
Lo que me gustaría hacer es tejer el archivo maestro, que luego llamaría al segundo archivo para cada subconjunto de datos e incluiría los resultados en un solo documento. A continuación se muestra un ejemplo simple.
Documento maestro:
# My report
```{r}
library(iterators)
data(mtcars)
```
```{r create-iterator}
cyl.i <- iter(unique(mtcars$cyl))
```
## Generate report for each level of cylinder variable
```{r cyl4-report, child=''analysis-template.Rmd''}
```
```{r cyl6-report, child=''analysis-template.Rmd''}
```
```{r cyl8-report, child=''analysis-template.Rmd''}
```
analysis-template.Rmd:
```{r, results=''asis''}
cur.cyl <- nextElem(cyl.i)
cat("###", cur.cyl)
```
```{r mpg-histogram}
hist(mtcars$mpg[mtcars$cyl == cur.cyl], main = paste(cur.cyl, "cylinders"))
```
```{r weight-histogam}
hist(mtcars$wt[mtcars$cyl == cur.cyl], main = paste(cur.cyl, "cylinders"))
```
El problema es que knitr no permite etiquetas de fragmentos no únicas, por lo que el tricotado falla cuando se llama a analysis-template.Rmd
segunda vez. Este problema podría evitarse al dejar los fragmentos sin nombre, ya que las etiquetas únicas se generarían automáticamente. Sin embargo, esto no es ideal porque me gustaría utilizar las etiquetas de fragmentos para crear nombres de archivos informativos para las parcelas exportadas.
Una posible solución sería usar una función simple que anexa el cilindro actual a la etiqueta del trozo:
```r{paste(''cur-label'', cyl, sep = "-")}
```
Pero no parece que knitr evaluará una expresión en la posición de la etiqueta del fragmento.
También traté de usar un gancho personalizado que modificó la etiqueta del fragmento actual:
knit_hooks$set(cyl.suffix = function(before, options, envir) {
if (before) options$label <- "new-label"
})
Pero cambiar la etiqueta del fragmento no afectaba a los nombres de archivo de las gráficas generadas, así que no creía que knitr utilizara la nueva etiqueta.
¿Alguna idea sobre cómo cambiar las etiquetas de los fragmentos para que el mismo documento secundario se pueda llamar varias veces? ¿O tal vez una estrategia alternativa para lograr esto?
Si haces todos los trozos en tu ** anónimo, es decir, ```{r}
funciona. Esto, por supuesto, no es muy elegante, pero hay dos problemas que le impiden cambiar la etiqueta del fragmento actual:
- Un archivo se analiza antes de que se ejecuten los bloques de código. El analizador ya detecta etiquetas duplicadas, antes de ejecutar cualquier código o llamar a ganchos personalizados.
- Las opciones de fragmento (incluida la etiqueta) se procesan antes de llamar al gancho (lógico: es una opción que desencadena un gancho), por lo que el gancho ya no puede cambiar la etiqueta.
El hecho de que los bloques sin nombre funcionen es que internamente reciben la etiqueta número unnamed-chunk-
+ número.
Los bloques no pueden tener nombres duplicados ya que knitr internamente hace referencia a ellos por etiqueta. Una solución podría ser hacer que knitr agregue el número de fragmento a todos los fragmentos con nombres duplicados. O hacer referencia a ellos por número de fragmento en lugar de etiqueta, pero eso me parece un cambio mucho mayor.