Print a list of sites with dynamic size in knitr

I want to be able to print an undefined list of graphs in knitr. I can do this, but there are a few wrinkles left so that they can be smoothed out. Namely:

1) How do you suppress list indexes (for example, [[2]]) on every page preceding each plot? Using echo = FALSE does nothing.

2) Is it possible to set the size for each plot as it is rendered? I tried to set the size variable outside of the chunk, but this only allows me to use one value and not another value for each plot.

I ask this as one question, because they seem to be talking in the same lesson, i.e. create a list of stories.

Code example:

\documentclass{article} \usepackage[margin=.5in, landscape]{geometry} \begin{document} <<diamond_plots, echo = FALSE, results = 'hide'>>== library(ggplot2) diamond_plot = function(data, cut_type){ ggplot(data, aes(color, fill=cut)) + geom_bar() + ggtitle(paste("Cut:", cut_type, sep = "")) } cuts = unique(diamonds$cut) plots = list() for(i in 1:length(cuts)){ data = subset(diamonds, cut == cuts[i]) plots[[i]] = diamond_plot(data, cuts[i]) } height = 3 @ <<print_plots, results='asis', echo=FALSE, fig.width=10, fig.height=height>>= plots @ \end{document} 

PDF graphics are as follows:

enter image description here

+5
source share
2 answers

1) How do you suppress list indexes (for example, [[2]]) on every page preceding each plot? Using echo = FALSE does nothing.

Separate each item in the list separately ( lapply ) and hide the output from lapply ( invisible ):

 invisible(lapply(plots, print)) 

2) Is it possible to set the size for each plot as it is rendered? I tried to set the size variable outside the chunk, but this allowed me to use only one value, and not another value for each plot.

Yes. In the general case, when you pass vectors to the fragment parameters associated with the shapes, the i th element is used to plot i th . This refers to parameters that are “specific figures,” for example, for example. fig.cap , fig.scap , out.width and out.height .

However, the other parameters of the figure are “device specific”. To understand this, it is important to take a look at option dev :

dev : the name of the function that will be used as the graphic device for recording the graphs [...], options dev , fig.ext , fig.width , fig.height and dpi can be vectors (in short, they will be processed), for example <<foo, dev=c('pdf', 'png')>>= creates two files for the same chart: foo.pdf and foo.png

When transferring a vector to the optional “figure” out.height , the i th element used for the i th out.height is important; transferring the vector to the device-specific parameter has the consequence of the i th element used for the i th device.

Therefore, to generate charts with dynamic size, you need to crack pieces a little, because one piece cannot generate charts with different fig.height settings. The following solution is based on the example of knitr `075-knit-expand.Rnw and this post on r-bloggers.com (which explains this answer on SO ).

The idea of ​​the solution is to use a piece template and expand the template values ​​using appropriate expressions to generate fragments, which, in turn, generate graphs with the correct fig.height setting. The extended template is passed to knit to evaluate the fragment:

 \documentclass{article} \begin{document} <<diamond_plots, echo = FALSE, results = "asis">>== library(ggplot2) library(knitr) diamond_plot = function(data, cut_type){ ggplot(data, aes(color, fill=cut)) + geom_bar() + ggtitle(paste("Cut:", cut_type, sep = "")) } cuts = unique(diamonds$cut) template <- "<<plot-cut-{{i}}, fig.height = {{height}}, echo = FALSE>>= data = subset(diamonds, cut == cuts[i]) plot(diamond_plot(data, cuts[i])) @" for (i in seq_along(cuts)) { cat(knit(text = knit_expand(text = template, i = i, height = 2 * i), quiet = TRUE)) } @ \end{document} 

The template is expanded using knit_expand , which replaces the expressions in {{}} with the appropriate values.

It is important to use quite = TRUE to call knit . Otherwise, knit pollute the main document with journal information.

Using cat is important to avoid an implicit print that would otherwise distort the result. For the same reason, the "outer" fragment ( diamond_plots ) uses results = "asis" .

+6
source

You need to access individual list items, otherwise printing will always print indexes.

Not sure if this is the cleanest answer, but you can just print them in a loop.

 > print(plots) [[1]] [[2]] [[3]] [[4]] [[5]] > for(x in plots){print(x)} 

But I have not tried this in tex, just a console.

0
source

Source: https://habr.com/ru/post/1235917/


All Articles