Figures and tables
Figures are really easy in knitr. Tables are not quite so easy, but the ability to produce fully reproducible tables is really important. You should never be copy-pasting or retyping data summaries into a table.
Figures
Figures are super easy in knitr. For the most part, you don’t need to do anything. If a code chunk produces a figure, it will automatically be produced and inserted into the final document. If a code chunk produces a bunch of figures, then a bunch of image files will be produced and inserted into the final document.
Consider this example:
```{r bunch-o-figs, fig.height=4, fig.width=8}
n <- 100
x <- rnorm(n)
par(mfrow=c(1,2), las=1)
for(i in 1:8) {
y <- i*x + rnorm(n)
plot(x, y, main=i)
}
```
The par(mfrow=c(1,2))
makes multi-panel figures that have one row
and two columns. But the for
loop makes 8 figures, so this will
produce four image files, each with a pair of panels,
side-by-side. All four will appear, one by one, in the
final document.
Here’s what that chunk would produce, plus an R Markdown file with just that chunk.
For R Markdown, the default graphics device is png
. You can choose
a different device using the chunk option dev
. For example, to use
the svg
device (for
Scalable Vector Graphics,
which may look better in a web page as they can be scaled without loss
of quality), you would use dev='svg'
, as follows:
```{r bunch-o-figs-svg, fig.height=4, fig.width=8, dev='svg'}
n <- 100
x <- rnorm(n)
par(mfrow=c(1,2), las=1)
for(i in 1:8) {
y <- i*x + rnorm(n)
plot(x, y, main=i)
}
```
Here’s what that chunk would produce, plus an R Markdown file with just that chunk.
You can pass arguments to the graphics device using the chunk option
dev.args
, which takes a list. For example:
```{r bunch-o-figs-pointsize, fig.height=4, fig.width=8, dev.args=list(pointsize=18)}
n <- 100
x <- rnorm(n)
par(mfrow=c(1,2), las=1)
for(i in 1:8) {
y <- i*x + rnorm(n)
plot(x, y, main=i)
}
```
The chunk option dev.args=list(pointsize=18)
passes pointsize=18
to the png()
device. This is equivalent to, in R, using
png("myfile.png", pointsize=18)
.
Here’s what that chunk would produce, plus an R Markdown file with just that chunk.
For more information on graphics with knitr, see the Knitr graphics manual.
Tables
I try to avoid tables; figures are almost always better. And for informal reports, I’ll often just print out a matrix or data frame, rather than create a formal table.
kable
If you want to make a somewhat nicer table, the simplest approach is
to use the kable
function in the knitr
package. It doesn’t have
many options, but in many cases it’s sufficient. Here’s an example.
```{r kable}
n <- 100
x <- rnorm(n)
y <- 2*x + rnorm(n)
out <- lm(y ~ x)
library(knitr)
kable(summary(out)$coef, digits=2)
```
Here’s what that chunk would produce, plus an R Markdown file with just that chunk.
pander
Another good option is the
pander package.
It allows more customization, and if you give it the output of lm()
,
it will automatically produce the table of regression coefficients
that we’re interested in.
```{r pander}
n <- 100
x <- rnorm(n)
y <- 2*x + rnorm(n)
out <- lm(y ~ x)
library(pander)
panderOptions("digits", 2)
pander(out)
```
Here’s what that chunk would produce, plus an R Markdown file with just that chunk.
xtable
If you want more precise control of the appearance of the table, use
the xtable
function in the
xtable package.
Here’s the above example, using xtable:
```{r xtable, results="asis"}
n <- 100
x <- rnorm(n)
y <- 2*x + rnorm(n)
out <- lm(y ~ x)
library(xtable)
tab <- xtable(summary(out)$coef, digits=c(0, 2, 2, 1, 2))
print(tab, type="html")
```
Here you need to use the chunk option results="asis"
, as otherwise the
html code will be printed as if it were R output.
Here’s what that chunk would produce, plus an R Markdown file with just that chunk.
Up next
Read my comments on reproducibility, and perhaps about Knitr with AsciiDoc or Knitr with LaTeX.