In a R Notebook there is a function that makes many plots and print summary statistics in the console. I would like to get the plot and the console output (i.e. summary statistics) side by side on the HTML output.
Here is a very simple example:
---
title: "Example"
output: html_notebook
---
```{r}
mapply(FUN = function(.x) {
plot(.x)
summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```
The output of the above code looks like:
As you can see, plots are one after the other and console outputs are somewhere in the middle-end.
The expected output looks like:
I went through these SO topics without success:
Please note that I am really trying to get the console output, if possible I would like to avoid using many tranformation to get a grob or a picture as, sometimes, relevant methods for my actual outputs do not exist. It is ok no to use R Notebook but RMarkdown instead.
It's not perfect. For example, I didn't add in handlers for screen size. However, I can. You would have to let me know what you're looking for, though.
This uses Javascript in R Markdown. The engine for this is built-in. However, I added the code for you to check it (should you so choose): names(knitr::knit_engines$get())
.
Also, in the setup
chunk, I added options(width = 75)
. This will affect all chunk outputs. You can change this to make it a chunk-specific option. However, the default is 80, so you probably won't notice a difference. I did this because for two of the three groups, Species
wrapped to the next row. However, for versicolor
, it was different. This is part of the enforcement for uniformity.
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
# confirm engine for 'js' (it was #37 for me)
names(knitr::knit_engines$get())
# set the output width for chunks' render
# this is to keep the summaries even (versicolor was doing its own thing)
options(width = 75)
library(tidyverse)
```
The styles are not in a chunk. This goes between the setup and the next chunk.
<style>
.setupCols {
display:flex;
flex-direction:row;
width: 100%;
}
.setupCols p{
display:flex;
flex-direction: column;
width: 45%;
}
.setupCols pre {
display:flex;
flex-direction: column;
width: 55%
}
.setupCols pre code {
font-size: 85%;
}
</style>
Next is some code before your mapply
call and code after.
<div class="setupCols">
```{r graphOne}
mapply(FUN = function(.x) {
plot(.x)
summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```
</div>
At any point in time after this chunk, you will add a styling chunk. If you want it to apply more than once, move this chunk to the end. If you only want it to apply to the chunk (I named) graphOne
, then make it the next chunk.
```{r styler,results='asis',engine='js'}
// search for class and tags
elem = document.querySelector('div.setupCols > pre > code');
// remove hashtags
elem.innerHTML = elem.innerHTML.replace(/#{2}/g, '');
// add newlines between summaries
elem.innerHTML = elem.innerHTML.replace(/\s{9}\n/g, '<br /><br />')
```
If you run this chunk inline, you will not get any output. However, you will see this output when you knit
.
I also added some text here, but this is what it looks like:
If you wanted to see what the Javascript is doing, you could add eval = F
and knit
. This is what it will look like:
Let me know if I missed something or if you have any questions.