Search code examples
rknitrrnw

Modify external R script in a knitr chunk


I'm wondering if it's possible to hook into the code in an external R script that is read by knitr.

Specifically, say that you have the following R file

test.R

## ---- CarPlot
library(ggplot2)
CarPlot <- ggplot() +
    stat_summary(data = mtcars,
                 aes(x = factor(gear),
                     y = mpg
                     ),
                 fun.y = "mean",
                 geom = "bar"
                 )
CarPlot

Imagine that you wanted to use this graph in multiple reports, but in one of these reports you want the graph to have a title and in the other report you do not.

Ideally, I would like to be able to use the same external R script to be able to do this so that I do not have to make changes to multiple R files in case I decide to change something about the graph.

I thought that one way to perhaps do this would be by setting the fig.show chunk option to hold—since it will "hold all plots and output them in the very end of a code chunk"—and then appending a title to the plot like so:

test.Rnw

\documentclass{article}

\begin{document}

<<external-code, cache=FALSE,echo=FALSE>>=
read_chunk('./test.R')
@

<<CarPlot,echo=FALSE,fig.show='hold'>>=
CarPlot <- CarPlot + ggtitle("Plot about cars")
@

\end{document}

This, however, does not work. Although the plot is printed, the title that I tried to append does not show up.

Is there some way to do what I would like to do?


Solution

  • You don't want to show the plot created by test.R, so you should set fig.show = 'hide' or include = FALSE for that chunk:

    <<external-code, cache=FALSE,echo=FALSE,fig.show = 'hide'>>=
    read_chunk('./test.R')
    @
    

    You do want to show the plot after modification, so you have to print it:

    <<CarPlot,echo=FALSE>>=
    CarPlot <- CarPlot + ggtitle("Plot about cars")
    CarPlot
    @
    

    fig.show = 'hold' is used if you have a large code chunk that prints a plot in the middle, but you don't want the plot to show in your document until the end. It doesn't apply to this case.