Unpredictable figure size in RMD chunk in code loop - r-markdown

I have an rmd chunk of r code with a loop. The structure of the code is like this:
```{r echo=FALSE, results="asis", out.width="100%"}
## out.width="100%"
## fig.width=12
## fig.height=(6+2*ceiling(6/4))
section_number <- 3
i = 1 ## for testing
while (i <= length(target_var_list)) {
target_var <- target_var_list[i]
data_segments <- data_segments(wrangled_devices, target_var)
# Code
exposure_chart_data <- monkeyr::get_exposure_chart_data(wrangled_obs, wrangled_devices, target_var)
exposure_plot <- monkeyr::get_exposure_plot(exposure_chart_data, target_var)
# knitr::opts_chunk$set(fig.height=(6+2*ceiling(data_segments/4)))
print(exposure_plot)
# print(exposure_plot, fig.height=(12+2*ceiling(data_segments/4)))
section_number <- section_number + 1
cat("\n\n\n")
i <- i + 1
}
```
I have commented out a few attempts I made to control the width and height of the plot. And I have commented out 2 attempts I made to control the knitr behaviour on a per plot basis.
The problem is that I can't find a reliable way to control the plot size that accommodates different lengths of the target_var_length.
It is possible to control the height at chunk level, but that is then fixed, and won't respond to each element in the loop. Here are some viz. What I would like is for the actual bar to be the same size in every case. So the case with 3 values would be 75% as wide as the 4. And the case with 7 would look be 2 rows, so twice the height of the 4. Do you see what I mean...

After quite a few hours of messing around with different approaches, here are some insights and an answer.
knitr::opts_chunk$set
I expected this to take effect on execution and change the chunk options for whatever elements follow. To change the plot height based on the number of rows / column in a facetted plot, I tried this:
knitr::opts_chunk$set(fig.height=(6+2*ceiling(data_segments/4)))
However it has no effect. The documentation bears this out. This actually sets the default chunk settings for subsequent chunks, and has no effect whatsoever on the current chunk. I encountered another function:
knitr::opts_current$set(fig.height=(6+2*ceiling(data_segments/4)))
The documentation as much as warns you off using this. And I found that it didn't achieve the expected results either in any case.
Blind Hope
I considered the possibility that I was overthinking this and left it up to blind hope by removing all efforts to control the height. Sometimes things just work out you know! ... They didn't.
Using an rmd child chunk
This is the approach that I finally got to work. It's a slightly horrible hack. My first effort was to create a separate rmd file for each plot:
```{r echo=FALSE, results="asis", out.width="100%", fig.height=(6+2*ceiling(data_segments/4))}
print(myPlot)
```
But that meant creating lots of new rmd plots. I have a major problem with how messy that would get. So I cleaned it up by using a single rmd file for any plot and lumped the code to call it into a fucntion.
resize_plot <- function(resizePlot, resizeHeight) {
resizePlot <- resizePlot
resizeHeight <- resizeHeight
res <- knitr::knit_child('resizePlot.rmd', quiet = TRUE)
cat(res, sep = '\n')
}
Now to insert a custom height plot I just call my new function:
resize_plot(exposure_plot, 3.25*ceiling(data_segments/4))
And the single rmd file just looks like this:
```{r echo=FALSE, results="asis", out.width="100%", fig.height=resizeHeight}
print(resizePlot)
```
And bingo - it looks perfect!

Related

R markdown summary output

I would like to keep all the columns of the summary output in same line, do you have a solution?
as shown in the picture, the last column goes to a new line, how to avoid it?
Thanks a lot in advance!
Without a code example, I can't help edit the code. In your Rmarkdown initial set up chunk, put the code below
```
{r setup}
knitr::opts_chunk$set(echo = TRUE)
options(width = 1000)
```
the width = 1000 will need to be adjusted to meet your needs.
here is a link that might help you get more information

Knit Markdown code blocks with Rmd Chunk Code Styling

I have many markdown files, each with many codeblocks, see an example below. (They were converted to this format via pandoc from other file types)
I would like to knit these in as Rmd files. Right now, the codeblocks have no decorators. When I knit the file below, there is no code syntax styling/coloring. I do not want to evaluate the code, I just want to print them out, hence: knitr::opts_chunk$set(warning=FALSE, message=FALSE, cache=FALSE).
Suppose all the code are MATLAB code, is there something I can add like: knitr::opts_chunk$set(code=MATLAB), so that they would all get MATLAB code styling/coloring?
My code chunks are actually all MATLAB code, so MATLAB stlying/coloring would be more helpful, but any code styling would be great to make the code chunks in outputted HTML/PDF etc easier to read.
---
title: matlab code in blocks
output: html_document
---
# RMD file with Markdown Code Blocks
```{r global_options, include = FALSE}
knitr::opts_chunk$set(warning=FALSE, message=FALSE, cache=FALSE)
```
## Example 1
Here is a code block A
fl_fig_wdt = 3;
fl_fig_hgt = 2.65;
figure('PaperPosition', [0 0 fl_fig_wdt fl_fig_hgt], 'Renderer', 'Painters');
x = rand([10,1]);
y = rand([10,1]);
scatter(x, y, 'filled');
grid on;
grid minor;
## Section 2
Here is a code block B
fl_fig_wdt = 5;
fl_fig_hgt = 5.65;
figure('PaperPosition', [0 0 fl_fig_wdt fl_fig_hgt], 'Renderer', 'Painters');
x = rand([20,1]);
y = rand([20,1]);
scatter(x, y, 'filled');
grid on;
grid minor;
End of file.
If you need a general solution, you need to use a Pandoc Lua filter (I'm not able to write one for you; see the Github issue that you cross-posted). If you only need HTML output, you may use JavaScript to add a class name to the code blocks, e.g., add this js code chunk to the end of your document:
```{js, echo=FALSE}
document.querySelectorAll('pre').forEach(function(el) {
// the class name is the language name
// (I'm using R here, although it's not the right name)
if (!el.className) el.className = 'r';
});
```
The output looks like this:

Change Default Beamer slide size

In R markdown when using Beamer slides if you try to plot you need to specify the plot sizes (unlike in the reports) so that the plots fit on a page. This can often result in the plots appearing to be squashed together, as apposed to just a smaller version of the plot.
Is there some method to change the default slide size to alleviate this problem?
I have tried
header-includes:
- \usepackage[papersize={25.6cm,19.2cm}]{geometry}
in the yaml header, and I get the error
! LaTeX Error: Missing \begin{document}.
Using R Markdown I shouldn't need to use this though.
A reproducible example is shown below
---
title: "Plots look bad"
author: "Beavis"
date: "`r format(Sys.time(), '%d/%m/%Y')`"
output: beamer_presentation
header-includes:
- \usepackage{float}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
knitr::opts_chunk$set(results = 'hide')
knitr::opts_chunk$set(warning = FALSE)
knitr::opts_chunk$set(cache=TRUE)
knitr::opts_chunk$set(fig.height=3.5)
```
# Introduction
```{r}
pca <- prcomp(iris[,1:4])
biplot(pca)
```
Here, you if you run this the second slide looks like this As you can see the plot is rubbish. What is the best way to avoid this problem?
The biplot function uses par(pty = "s") to force a square plot, so it's not going to fill a rectangular slide. You can make it look better by asking the fig.height to be bigger, but then it will overflow the bottom of the slide. To prevent this, you can set both fig.height to a large number, and out.height (which will be a LaTeX measurement) to something that will fit on a slide. For example, using this chunk
```{r fig.height=10, out.height="0.8\\textheight"}
pca <- prcomp(iris[,1:4])
biplot(pca)
```
I see this output:
I'd recommend a smaller fig.height, but your preference may be different.
Both fig.height and out.height could be specified using knitr::opts_chunk$set as defaults for all slides if you want.
You could also specify out.width="\\textwidth" for a really ugly stretched plot that fills the slide, but I wouldn't recommend it.

Caption numbering not in sequential order when citing the captions with captioner in Rmarkdown

I am using captioner (https://cran.r-project.org/web/packages/captioner/vignettes/using_captioner.html) to create table captions in Rmarkdown - the main reason is because I am using huxtable for conditional formatting and exporting to word. This is the only I have found to have numbered captions.
I was trying to reference the captions but the caption number is not in sequential order when citing the captions but only if the table_nums(..., display="cite") is before the tables. I was trying to give the range of table numbers and it changed the number of the last table. I The number isn't changed if the r table_nums('third_cars_table',display = "cite") is put after the captions. Is there a way to make sure that table numbers remain in sequential order? I'd also be happy with a better solution for numbered captions.
Reproducible example:
---
title: "Untitled"
output: bookdown::word_document2
---
```{r setup, include=FALSE}
library(captioner)
library(huxtable)
library(knitr)
library(pander)
table_nums <- captioner(prefix = "Table")
fig_nums <- captioner(prefix = "Figure")
knitr::opts_chunk$set(echo = TRUE)
```
## Description of tables
I am trying to put a description of tables
and say that these results are shown table numbers ranging
from the first table (`r table_nums('first_cars_table',display = "cite")`)
to the last table (`r table_nums('third_cars_table',display = "cite")`)
```{r, results='asis',echo=FALSE,eval.after=TRUE}
tablecap1=cat(table_nums(name="first_cars_table",caption='First car table'))
kable((cars[1:5,]))
tablecap2=cat(table_nums(name="second_cars_table",caption='second car table'))
kable(cars[6:10,])
tablecap3=cat(table_nums(name="third_cars_table",caption='third car table'))
kable(cars[10:15,])
```
The results:
A (terrible) workaround is to manually give the number ordering using display = FALSE. For example, inserting the following at the start of the document will ensure t1-t5 are sequentially numbered, no matter where the tables or first citations appear:
`r table_nums('t1', display = FALSE)`
`r table_nums('t2', display = FALSE)`
`r table_nums('t3', display = FALSE)`
`r table_nums('t4', display = FALSE)`
`r table_nums('t5', display = FALSE)`
I have not examined the captioner code but I expect that the document is read from top to bottom once and hence the numbering is stored in a first come, first served basis. Thus, I am not sure there are any other ways to get around this as it would involve some kind of pre-processing stage.

Adjust the output width of R Markdown HTML output

I am producing an HTML output but I am having issues with the output width of R code output.
I'm able to adjust the figure width with no difficulty but when I try to write a data table or the factor loadings, R is outputting at a fixed width which is only about a third of my screen width. This results in the columns of the table being split up rather than all of the columns displayed in a single table.
Here is a reproducible example:
---
output: html_document
---
# Title
```{r echo = FALSE, fig.width=16, fig.height=6}
x = matrix(rnorm(100),ncol=10)
x
plot(x)
```
Add this at the start of your document:
```{r set-options, echo=FALSE, cache=FALSE}
options(width = SOME-REALLY-BIG-VALUE)
```
Obviously, replace SOME-REALLY-BIG-VALUE with a number. But do you really want to do all that horizontal scrolling?
Your output is probably being wrapped somewhere around 80 characters or so.
Also, you can temporarily change the local R options for a code chunk:
```{r my-chunk, R.options = list(width = SOME-BIG-VALUE)}
```