A minimal reproducible example consists of the following items :
- a minimal dataset, necessary to reproduce the error
- the minimal runnable code necessary to reproduce the error, which can be run on the given dataset.
- the necessary information on the used packages, R version and system it is run on.
- in case of random processes, a seed (set by
set.seed()
) for reproducibility
Looking at the examples in the help files of the used functions is often helpful. In general, all the code given there fulfills the requirements of a minimal reproducible example : data is provided, minimal code is provided, and everything is runnable.
Producing a minimal dataset
For most cases, this can be easily done by just providing a vector / dataframe with some values. Or you can use one of the built-in datasets, which are provided with most packages.
Making a vector is easy. Sometimes it is necessary to add some randomness to it, and there are a whole number of functions to make that. sample()
can randomize a vector, or give a random vector with only a few values. letters
is a useful vector containing the alphabet. This can be used for making factors.
A few examples :
- random values :
x <- rnorm(10)
for normal distribution,x <- runif(10)
for uniform distribution, ... - a permutation of some values :
x <- sample(1:10)
for vector 1:10 in random order. - a random factor :
x <- sample(letters[1:4], 20, replace = TRUE)
For matrices, one can use matrix()
, eg :
matrix(1:10, ncol =2)
Making dataframes can be done using data.frame()
. One should pay attention to name the entries in the dataframe, and to not make it overly complicated.
An example :
Data <- data.frame(
X = sample(1:10),
Y = sample(c("yes","no"),10, replace =TRUE))
For some questions, specific formats can be needed. For these, one can use any of the provided as.someType
functions : as.factor
, as.Date
, as.xts
, ... These in combination with the vector and/or dataframe tricks.
Copy your data
If you have some data that would be too difficult to construct using these tips, then you can always make a subset of your original data, using eg head()
, subset()
or the indices. Then use eg. dput()
to give us something that can be put in R immediately :
> dput(head(iris,4))
structure(list(Sepal.Length = c(5.1,4.9,4.7,4.6), Sepal.Width = c(3.5,3,3.2,3.1), Petal.Length = c(1.4,1.4,1.3,1.5), Petal.Width = c(0.2,0.2,0.2,0.2), Species = structure(c(1L,1L,1L,1L), .Label = c("setosa","versicolor","virginica"), class ="factor")), .Names = c("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","Species"), row.names = c(NA,4L), class ="data.frame")
Worst case scenario, you can give a text representation that can be read in using the text
parameter of read.table
:
zz <-"Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa"
Data <- read.table(text=zz, header =TRUE)
Producing minimal code
This should be the easy part, but often isn't. What you should not do, is :
- add all kind of data conversions. Make sure the provided data is already in the correct format (unless that is the problem of course)
- copy-paste a whole function / chunk of code that gives an error. First try to locate which lines exactly result in the error. More often than not you'll find out what the problem is yourself.
What you should do, is :
- add which packages should be used if you use any.
- if you open connections or make files, add some code to close them or delete the files (using
unlink()
) - if you change options, make sure the code contains a statement to revert them back to the original ones. (eg
op <- par(mfrow=c(1,2)) ...some code... par(op)
) - testrun your code in a new, empty R session to make sure the code is runnable. People should be able to just copy-paste your data and your code in the console and get exactly the same as you have.
Give extra information
In most cases, just the R version and the operating system will suffice. When conflicts arise with packages, giving the output of sessionInfo()
can really help. When talking about connections to other applications (be it through ODBC or anything else), one should also provide version numbers for those, and if possible also the necessary information on the setup.