(This article was first published on

Recently I was writing a code allowing to plot multiple ggplot2 plots on one page. I wanted to replicate standard behavior of plot function that plots graphs in sequence according to mfrow/ mfcol option in par. The solution lead me to think of emulating C-like local static variables in R.**R snippets**, and kindly contributed to R-bloggers)There are several solutions to this problem but I think that a nice one is by adding attributes to a function. Here is a simple example:

f

**<-****function****(**x**)****{** y

**<-**attr**(**f, "sum"**)****if**

**(**is.null

**(**y

**))**

**{**

y

**<-**0**}**

y

**<-**x**+**y attr

**(**f, "sum"**)****<<-**y return

**(**y**)****}**

>

**for****(**i**in**1**:**5**)**cat**(**i, ": ", f**(**i**)**, "\n", sep**=**""**)**1: 1

2: 3

3: 6

4: 10

5: 15

As it can be seen attribute "sum" is static but it can be thought of as local because it is not stored directly as a variable in global environment.

And here is the application of the concept to the problem of plotting several qplots in a sequence:

library

**(**ggplot2**)**library

**(**grid**)**# setup the ploting grid and plotting sequence

mplot.setup

**<-****function****(**nrow, ncol, by.row**=****TRUE)****{** attributes

**(**mplot.seq**)****<<-**list**(**nrow**=**nrow, ncol**=**ncol, pos

**=**0, by.row**=**by.row**)** grid.newpage

**()** pushViewport

**(**viewport**(**layout**=**grid.layout**(**nrow, ncol**)))****}**

# plot at given grid location

mplot

**<-****function****(**graph, row, col**)****{** print

**(**graph, vp**=**viewport**(**layout.pos.row**=**row, layout.pos.col

**=**col**))****}**

# plot the at the next position in the sequence

mplot.seq

**<-****function****(**graph**)****{** pos

**<-**attr**(**mplot.seq, "pos"**)** nrow

**<-**attr**(**mplot.seq, "nrow"**)** ncol

**<-**attr**(**mplot.seq, "ncol"**)****if**

**(**attr

**(**mplot.seq, "by.row"

**))**

**{**

col

**<-**1**+****(**pos %% ncol**)** row

**<-**1**+****((**pos %/% ncol**)**%% nrow**)****}**

**else**

**{**

row

**<-**1**+****(**pos %% nrow**)** col

**<-**1**+****((**pos %/% nrow**)**%% ncol**)****}**

attr

**(**mplot.seq, "pos"**)****<<-**pos**+**1 mplot

**(**graph, row, col**)****}**

# application example

mplot.setup

**(**2,4,**FALSE****)****for**

**(**i

**in**1

**:**4

**)**

**{**

mplot.seq

**(**qplot**(**iris**[**,i**]**, xlab**=**names**(**iris**)[**i**]))** mplot.seq

**(**qplot**(**iris**[**,5**]**, iris**[**,i**]**, geom**=**"boxplot", xlab

**=**"Species", ylab**=**names**(**iris**)[**i**])****+**coord_flip**())****}**

The following plot is produced by the above code:

To

**leave a comment**for the author, please follow the link and comment on his blog:**R snippets**.R-bloggers.com offers

**daily e-mail updates**about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...