How to make a great R reproducible example?


How to make a great R reproducible example?
When discussing performance with colleagues, teaching, sending a bug report or searching for guidance on mailing lists and here on SO, a reproducible example is often asked and always helpful.
What are your tips for creating an excellent example? How do you paste data structures from r in a text format? What other information should you include?
Are there other tricks in addition to using dput()
, dump()
or structure()
? When should you include library()
or require()
statements? Which reserved words should one avoid, in addition to c
, df
, data
, etc?
dput()
dump()
structure()
library()
require()
c
df
data
How does one make a great r reproducible example?
@baptiste : The same minus the error. All techniques I explained are used in package help pages, and in tutorials and presentations I give about R
– Joris Meys
Oct 4 '11 at 15:11
The data is sometimes the limiting factor, as the structure may be too complex to simulate. To produce public data from private data: stackoverflow.com/a/10458688/742447 in stackoverflow.com/questions/10454973/…
– Etienne Low-Décarie
May 11 '12 at 21:41
23 Answers
23
A minimal reproducible example consists of the following items:
set.seed()
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.
For most cases, this can be easily done by just providing a vector/data frame with some values. Or you can use one of the built-in datasets, which are provided with most packages.
A comprehensive list of built-in datasets can be seen with library(help = "datasets")
. There is a short description to every dataset and more information can be obtained for example with ?mtcars
where 'mtcars' is one of the datasets in the list. Other packages might contain additional datasets.
library(help = "datasets")
?mtcars
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.
sample()
letters
A few examples :
x <- rnorm(10)
x <- runif(10)
x <- sample(1:10)
x <- sample(letters[1:4], 20, replace = TRUE)
For matrices, one can use matrix()
, eg :
matrix()
matrix(1:10, ncol = 2)
Making data frames can be done using data.frame()
. One should pay attention to name the entries in the data frame, and to not make it overly complicated.
data.frame()
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 data frame tricks.
as.someType
as.factor
as.Date
as.xts
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 :
head()
subset()
dput()
> 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")
If your data frame has a factor with many levels, the dput
output can be unwieldy because it will still list all the possible factor levels even if they aren't present in the the subset of your data. To solve this issue, you can use the droplevels()
function. Notice below how species is a factor with only one level:
dput
droplevels()
> dput(droplevels(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 = "setosa",
class = "factor")), .Names = c("Sepal.Length", "Sepal.Width",
"Petal.Length", "Petal.Width", "Species"), row.names = c(NA,
4L), class = "data.frame")
One other caveat for dput
is that it will not work for keyed data.table
objects or for grouped tbl_df
(class grouped_df
) from dplyr
. In these cases you can convert back to a regular data frame before sharing, dput(as.data.frame(my_data))
.
dput
data.table
tbl_df
grouped_df
dplyr
dput(as.data.frame(my_data))
Worst case scenario, you can give a text representation that can be read in using the text
parameter of read.table
:
text
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)
This should be the easy part but often isn't. What you should not do, is:
What you should do, is:
library()
unlink()
op <- par(mfrow=c(1,2)) ...some code... par(op)
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.
sessionInfo()
If you are running R in R Studio using rstudioapi::versionInfo()
can be helpful to report your RStudio version.
rstudioapi::versionInfo()
If you have a problem with a specific package you may want to provide the version of the package by giving the output of packageVersion("name of the package")
.
packageVersion("name of the package")
How do you use
dput
if the dataframe is very large and the problem is generated by the middle of the dataframe? Is there a way to use dput
to reproduce the mid-section of data, say rows 60 through 70?– BgnR
Apr 10 '14 at 13:12
dput
dput
@BgnR You can extract part of the data frame using indices, eg:
tmp <- mydf[50:70,]
followed by dput(mydf)
. If the data frame is really big, try isolating the problem and just submit the few lines that cause the problem.– Joris Meys
Apr 11 '14 at 11:27
tmp <- mydf[50:70,]
dput(mydf)
@JorisMeys: Is there a way to tell
head
or dput
to limit data to level N recursively? I'm trying to come up with reproducible example and my data is a list of data frames. So, dput(head(myDataObj))
seems not to be enough, as it generates an output file of 14MB size.– Aleksandr Blekh
Aug 4 '14 at 15:51
head
dput
dput(head(myDataObj))
@JorisMeys: Just FYI - posted question in the comment above as a separate question: stackoverflow.com/questions/25127026/….
– Aleksandr Blekh
Aug 4 '14 at 20:32
@Konrad The best thing you could do, is link to the file and give the minimal command to read in that file. That'll be less hassle than copy-pasting the output of dput() :)
– Joris Meys
Jan 3 '16 at 12:57
(Here's my advice from How to write a reproducible example . I've tried to make it short but sweet)
How to write a reproducible example.
You are most likely to get good help with your R problem if you provide a reproducible example. A reproducible example allows someone else to recreate your problem by just copying and pasting R code.
There are four things you need to include to make your example reproducible: required packages, data, code, and a description of your R environment.
Packages should be loaded at the top of the script, so it's easy to
see which ones the example needs.
The easiest way to include data in an email or Stack Overflow question is to use dput()
to generate
the R code to recreate it. For example, to recreate the mtcars
dataset in R,
I'd perform the following steps:
dput()
mtcars
dput(mtcars)
mtcars <-
Spend a little bit of time ensuring that your code is easy for others to
read:
make sure you've used spaces and your variable names are concise, but
informative
use comments to indicate where your problem lies
do your best to remove everything that is not related to the problem.
The shorter your code is, the easier it is to understand.
Include the output of sessionInfo()
in a comment in your code. This summarises your R
environment and makes it easy to check if you're using an out-of-date
package.
sessionInfo()
You can check you have actually made a reproducible example by starting up a fresh R session and pasting your script in.
Before putting all of your code in an email, consider putting it on Gist github . It will give your code nice syntax highlighting, and you don't have to worry about anything getting mangled by the email system.
reprex
in tidyverse
is a good package for producing minimal, reproducible example: github.com/tidyverse/reprex– mt1022
Jun 1 '17 at 7:24
reprex
tidyverse
Why would anyone put the code in a email?
– Gilgamesh
Mar 3 at 21:51
I routinely receive emails with code in them. I even receive emails with attached word documents that contain code. Sometimes I even get emails with attached word documents that contain SCREENSHOTS of code.
– hadley
Mar 4 at 14:46
Personally, I prefer "one" liners. Something along the lines:
my.df <- data.frame(col1 = sample(c(1,2), 10, replace = TRUE),
col2 = as.factor(sample(10)), col3 = letters[1:10],
col4 = sample(c(TRUE, FALSE), 10, replace = TRUE))
my.list <- list(list1 = my.df, list2 = my.df[3], list3 = letters)
The data structure should mimic the idea of writer's problem and not the exact verbatim structure. I really appreciate it when variables don't overwrite my own variables or god forbid, functions (like df
).
df
Alternatively, one could cut a few corners and point to a pre-existing data set, something like:
library(vegan)
data(varespec)
ord <- metaMDS(varespec)
Don't forget to mention any special packages you might be using.
If you're trying to demonstrate something on larger objects, you can try
my.df2 <- data.frame(a = sample(10e6), b = sample(letters, 10e6, replace = TRUE))
If you're working with spatial data via the raster
package, you can generate some random data. A lot of examples can be found in the package vignette, but here's a small nugget.
raster
library(raster)
r1 <- r2 <- r3 <- raster(nrow=10, ncol=10)
values(r1) <- runif(ncell(r1))
values(r2) <- runif(ncell(r2))
values(r3) <- runif(ncell(r3))
s <- stack(r1, r2, r3)
If you're in need of some spatial object as implemented in sp
, you can get some datasets via external files (like ESRI shapefile) in "spatial" packages (see the Spatial view in Task Views).
sp
library(rgdal)
ogrDrivers()
dsn <- system.file("vectors", package = "rgdal")[1]
ogrListLayers(dsn)
ogrInfo(dsn=dsn, layer="cities")
cities <- readOGR(dsn=dsn, layer="cities")
IMHO, when using
sample
or runif
it's prudent to set.seed
. At least, this the suggestion I've received when producing examples relaying on sampling or random number generation.– Konrad
Jun 25 at 16:16
sample
runif
set.seed
@Konrad I agree, but this may depend. If you're just trying to generate some numbers a seed may not be needed but if you're trying to understand something specific where fixed numbers are needed, a seed would be mandatory.
– Roman Luštrik
Jun 26 at 11:31
Inspired by this very post, I now use a handy functionreproduce(<mydata>)
when I need to post to StackOverflow.
reproduce(<mydata>)
If myData
is the name of your object to reproduce, run the following in R:
myData
install.packages("devtools")
library(devtools)
source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R")
reproduce(myData)
This function is an intelligent wrapper to dput
and does the following:
dput
dput
objName <- ...
# sample data
DF <- data.frame(id=rep(LETTERS, each=4)[1:100], replicate(100, sample(1001, 100)), Class=sample(c("Yes", "No"), 100, TRUE))
DF is about 100 x 102. I want to sample 10 rows, and a few specific columns
reproduce(DF, cols=c("id", "X1", "X73", "Class")) # I could also specify the column number.
This is what the sample looks like:
id X1 X73 Class
1 A 266 960 Yes
2 A 373 315 No Notice the selection split
3 A 573 208 No (which can be turned off)
4 A 907 850 Yes
5 B 202 46 Yes
6 B 895 969 Yes <~~~ 70 % of selection is from the top rows
7 B 940 928 No
98 Y 371 171 Yes
99 Y 733 364 Yes <~~~ 30 % of selection is from the bottom rows.
100 Y 546 641 No
==X==============================================================X==
Copy+Paste this part. (If on a Mac, it is already copied!)
==X==============================================================X==
DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L, 25L, 25L), .Label = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"), class = "factor"), X1 = c(266L, 373L, 573L, 907L, 202L, 895L, 940L, 371L, 733L, 546L), X73 = c(960L, 315L, 208L, 850L, 46L, 969L, 928L, 171L, 364L, 641L), Class = structure(c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L), .Label = c("No", "Yes"), class = "factor")), .Names = c("id", "X1", "X73", "Class"), class = "data.frame", row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L))
==X==============================================================X==
Notice also that the entirety of the output is in a nice single, long line, not a tall paragraph of chopped up lines.
This makes it easier to read on SO questions posts and also easier to copy+paste.
You can now specify how many lines of text output will take up (ie, what you will paste into StackOverflow). Use the lines.out=n
argument for this. Example:
lines.out=n
reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
yields:
reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
==X==============================================================X==
Copy+Paste this part. (If on a Mac, it is already copied!)
==X==============================================================X==
DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L,25L, 25L), .Label
= c("A", "B", "C", "D", "E", "F", "G", "H","I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U","V", "W", "X", "Y"), class = "factor"),
X1 = c(809L, 81L, 862L,747L, 224L, 721L, 310L, 53L, 853L, 642L),
X2 = c(926L, 409L,825L, 702L, 803L, 63L, 319L, 941L, 598L, 830L),
X16 = c(447L,164L, 8L, 775L, 471L, 196L, 30L, 420L, 47L, 327L),
X22 = c(335L,164L, 503L, 407L, 662L, 139L, 111L, 721L, 340L, 178L)), .Names = c("id","X1",
"X2", "X16", "X22"), class = "data.frame", row.names = c(1L,2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L))
==X==============================================================X==
Here is a good guide:
http://www.r-bloggers.com/three-tips-for-posting-good-questions-to-r-help-and-stack-overflow/
But the most important is: Just make sure that you make a small piece of code that we can run to see what the problem is. A usefull function for this is dput()
, but if you have very large data you might want to make a small sample dataset or only use the first 10 lines or so.
dput()
EDIT:
Also make sure that you identified where the problem is yourself. The example should not be an entire R script with "On line 200 there is an error". If you use the debugging tools in R (I love browser()
) and google you should be able to really identify where the problem is and reproduce a trivial example in which the same thing goes wrong.
browser()
The R-help mailing list has a posting guide which covers both asking and answering questions, including an example of generating data:
Examples: Sometimes it helps to
provide a small example that someone
can actually run. For example:
If I have a matrix x as follows:
> x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y"))
> x
x y
A 1 5
B 2 6
C 3 7
D 4 8
>
how can I turn it into a dataframe
with 8 rows, and three columns named
'row', 'col', and 'value', which have
the dimension names as the values of 'row' and 'col', like this:
> x.df
row col value
1 A x 1
...
(To which the answer might be:
> x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
varying=list(colnames(x)), times=colnames(x),
v.names="value", timevar="col", idvar="row")
)
The word small is especially important. You should be aiming for a minimal reproducible example, which means that the data and the code should be as simple as possible to explain the problem.
EDIT: Pretty code is easier to read than ugly code. Use a style guide.
Since R.2.14 (I guess) you can feed your data text representation directly to read.table:
df <- read.table(header=T, text="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
")
You can also use
read.table("clipboard", header=TRUE)
.– sebastian-c
Sep 17 '12 at 1:09
read.table("clipboard", header=TRUE)
@sebastian-c how is that good for making reproducible example?? :)
– TMS
May 24 '14 at 8:43
@TMS Giving it serious thought, if the asker has supplied the data and the problem is small (but might have a few solutions), then it might be faster and you can still follow all the steps.
– sebastian-c
May 26 '14 at 17:52
Sometimes the problem really isn't reproducible with a smaller piece of data, no matter how hard you try, and doesn't happen with synthetic data (although it's useful to show how you produced synthetic data sets that did not reproduce the problem, because it rules out some hypotheses).
If you can't do either of these then you probably need to hire a consultant to solve your problem ...
edit: Two useful SO questions for anonymization/scrambling:
For producing synthetic data sets, the answers to this question give useful examples, including applications of
fitdistr
and fitdistrplus
.– Iterator
Oct 23 '11 at 13:47
fitdistr
fitdistrplus
The answers so far are obviously great for the reproducibility part. This is merely to clarify that a reproducible example cannot and should not be the sole component of a question. Don't forget to explain what you want it to look like and the contours of your problem, not just how you have attempted to get there so far. Code is not enough; you need words also.
Here's a reproducible example of what to avoid doing (drawn from a real example, names changed to protect the innocent):
The following is sample data and part of function I have trouble with.
code
code
code
code
code (40 or so lines of it)
How can I achieve this ?
To quickly create a dput
of your data you can just copy (a piece of) the data to your clipboard and run the following in R:
dput
for data in Excel:
dput(read.table("clipboard",sep="t",header=TRUE))
for data in a txt file:
dput(read.table("clipboard",sep="",header=TRUE))
You can change the sep
in the latter if necessary.
This will only work if your data is in the clipboard of course.
sep
I have a very easy and efficient way to make a R example that has not been mentioned above.
You can define your structure firstly.For example,
mydata <- data.frame(a=character(0), b=numeric(0), c=numeric(0), d=numeric(0))
>fix(mydata)
Then you can input your data manually.This is efficient for smaller examples rather than big ones.
...then
dput(mydata)
– GSee
Mar 8 '14 at 16:46
dput(mydata)
What is your frontend? It would be nice to have a complete answer. Etc make a data which you can directly loop like
for (d in data) ...
.– Léo Léopold Hertz 준영
Oct 30 '16 at 7:38
for (d in data) ...
Your main objective in crafting your questions should be to make it as easy as possible for readers to understand and reproduce your problem on their systems. To do so:
This does take some work but seems like a fair trade-off since you are asking others to do work for you.
The best option by far is to rely on built-in datasets. This makes it very easy for others to work on your problem. Type data()
at the R prompt to see what data is available to you. Some classic examples:
data()
iris
mtcars
ggplot2::diamonds
See this SO QA for how to find data sets suitable for your problem.
If you are able to rephrase your problem to use the built-in datasets you are much more likely to get good answers (and upvotes).
If your problem is very specific to a type of data that is not represented in the existing data sets, then provide the R code that generates the smallest possible dataset that your problem manifests itself on. For example
set.seed(1) # important to make random data reproducible
myData <- data.frame(a=sample(letters[1:5], 20, rep=T), b=runif(20))
Now someone trying to answer my question can copy/paste those two lines and start working on the problem immediately.
As a last resort, you can use dput
to transform a data object to R code (e.g. dput(myData)
). I say as a "last resort" because the output of dput
is often fairly unwieldy, annoying to copy-paste, and obscures the rest of your question.
dput
dput(myData)
dput
Someone once said:
A picture of expected output is worth 1000 words
-- a very wise person
If you can add something like "I expected to get this result":
cyl mean.hp
1: 6 122.28571
2: 4 82.63636
3: 8 209.21429
to your question, people are much more likely to quickly understand what you are trying to do. If your expected result is large and unwieldy, then you probably haven't thought enough about how to simplify your problem (see next).
The main thing to do is to simplify your problem as much as possible before you ask your question. Re-framing the problem to work with the built-in datasets will help a lot in this regard. You will also often find that just by going through the process of simplification you will answer your own problem.
Here are some examples of good questions:
In both cases, the user's problems are almost certainly not with the simple examples they provide. Rather they abstracted the nature of their problem and applied it to a simple data set to ask their question.
This answer focuses on what I think is the best practice: use built-in data sets and provide what you expect as a result in a minimal form. The most prominent answers focus on other aspects. I don't expect this answer to rising to any prominence; this is here solely so that I can link to it in comments to newbie questions.
Reproducible code is key to get help. However, there are many users that might be skeptical of pasting even a chunk of their data. For instance, they could be working with sensitive data or on an original data collected to use in a research paper. For any reason, I thought it would be nice to have a handy function for "deforming" my data before pasting it publicly. The anonymize
function from the package SciencesPo
is very silly, but for me it works nicely with dput
function.
anonymize
SciencesPo
dput
install.packages("SciencesPo")
dt <- data.frame(
Z = sample(LETTERS,10),
X = sample(1:10),
Y = sample(c("yes", "no"), 10, replace = TRUE)
)
> dt
Z X Y
1 D 8 no
2 T 1 yes
3 J 7 no
4 K 6 no
5 U 2 no
6 A 10 yes
7 Y 5 no
8 M 9 yes
9 X 4 yes
10 Z 3 no
Then I anonymize it:
> anonymize(dt)
Z X Y
1 b2 2.5 c1
2 b6 -4.5 c2
3 b3 1.5 c1
4 b4 0.5 c1
5 b7 -3.5 c1
6 b1 4.5 c2
7 b9 -0.5 c1
8 b5 3.5 c2
9 b8 -1.5 c2
10 b10 -2.5 c1
One may also want to sample few variables instead of the whole data before apply anonymization and dput command.
# sample two variables without replacement
> anonymize(sample.df(dt,5,vars=c("Y","X")))
Y X
1 a1 -0.4
2 a1 0.6
3 a2 -2.4
4 a1 -1.4
5 a2 3.6
Often you need some data for an example, however, you don't want to post your exact data. To use some existing data.frame in established library, use data command to import it.
e.g.,
data(mtcars)
and then do the problem
names(mtcars)
your problem demostrated on the mtcars data set
Many built-in data sets (like popular
mtcars
and iris
datasets) don't actually need the data
call to be used.– Gregor
Jul 17 '13 at 19:17
mtcars
iris
data
If you have large dataset which cannot be easily put to the script using dput()
,
post your data to pastebin and load them using read.table
:
dput()
read.table
d <- read.table("http://pastebin.com/raw.php?i=m1ZJuKLH")
Inspired by @Henrik.
I am developing the wakefield package to address this need to quickly share reproducible data, sometimes dput
works fine for smaller data sets but many of the problems we deal with are much larger, sharing such a large data set via dput
is impractical.
dput
dput
About:
wakefield allows the user to share minimal code to reproduce data. The user sets n
(number of rows) and specifies any number of preset variable functions (there are currently 70) that mimic real if data (things like gender, age, income etc.)
n
Installation:
Currently (2015-06-11), wakefield is a GitHub package but will go to CRAN eventually after unit tests are written. To install quickly, use:
if (!require("pacman")) install.packages("pacman")
pacman::p_load_gh("trinker/wakefield")
Example:
Here is an example:
r_data_frame(
n = 500,
id,
race,
age,
sex,
hour,
iq,
height,
died
)
This produces:
ID Race Age Sex Hour IQ Height Died
1 001 White 33 Male 00:00:00 104 74 TRUE
2 002 White 24 Male 00:00:00 78 69 FALSE
3 003 Asian 34 Female 00:00:00 113 66 TRUE
4 004 White 22 Male 00:00:00 124 73 TRUE
5 005 White 25 Female 00:00:00 95 72 TRUE
6 006 White 26 Female 00:00:00 104 69 TRUE
7 007 Black 30 Female 00:00:00 111 71 FALSE
8 008 Black 29 Female 00:00:00 100 64 TRUE
9 009 Asian 25 Male 00:30:00 106 70 FALSE
10 010 White 27 Male 00:30:00 121 68 FALSE
.. ... ... ... ... ... ... ... ...
If you have one or more factor
variable(s) in your data that you want to make reproducible with dput(head(mydata))
, consider adding droplevels
to it, so that levels of factors that are not present in the minimized data set are not included in your dput
output, in order to make the example minimal:
factor
dput(head(mydata))
droplevels
dput
dput(droplevels(head(mydata)))
I wonder if an http://www.r-fiddle.org/ link could be a very neat way of sharing a problem. It receives a unique ID like and one could even think about embedding it in SO.
http://www.r-fiddle.org/#/help
but doesn't work anymore...
– Moody_Mudskipper
Feb 19 at 17:00
Too bad - admittedly I completely forgot about reliability of some web setvice when I posted the answer back then. I somehow expected a useful service to persist.
– CMichael
Feb 20 at 15:48
Please do not paste your console outputs like this :
If I have a matrix x as follows:
> x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y")))
> x
x y
A 1 5
B 2 6
C 3 7
D 4 8
>
how can I turn it into a dataframe with 8 rows, and three
columns named `row`, `col`, and `value`, which have the
dimension names as the values of `row` and `col`, like this:
> x.df
row col value
1 A x 1
...
(To which the answer might be:
> x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
+ varying=list(colnames(x)), times=colnames(x),
+ v.names="value", timevar="col", idvar="row")
)
We can not copy-paste it directly.
To make questions and answers properly reproducible, try to remove +
& >
before posting it and put #
for outputs and comments like this:
+
>
#
#If I have a matrix x as follows:
x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y")))
x
# x y
#A 1 5
#B 2 6
#C 3 7
#D 4 8
#how can I turn it into a dataframe with 8 rows, and three
#columns named `row`, `col`, and `value`, which have the
#dimension names as the values of `row` and `col`, like this:
#x.df
# row col value
#1 A x 1
#...
#To which the answer might be:
x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
varying=list(colnames(x)), times=colnames(x),
v.names="value", timevar="col", idvar="row")
One more thing, if you have used any function from certain package, mention that library.
do you remove the
>
and add the #
manually or is there an automatic way to do that?– BCArg
Jul 7 '17 at 8:22
>
#
@BCArg I remove
>
manually. But, for addition of #
, I use Ctrl+Shift+C
shortcut in RStudio
editor.– user2100721
Jul 22 '17 at 15:15
>
#
Ctrl+Shift+C
RStudio
Apart of all above answers which I found very interesting, it could sometimes be very easy as it is discussed here :- HOW TO MAKE A MINIMAL REPRODUCIBLE EXAMPLE TO GET HELP WITH R
There are many ways to make a random vector Create a 100 number vector with random values in R rounded to 2 decimals or random matrix in R
mydf1<- matrix(rnorm(20),nrow=20,ncol=5)
Note that sometimes it is very difficult to share a given data because of various reasons such as dimension etc. However, all above answers are great and very important to think and use when one wants to make a reproducible data example. But note that in order to make a data as representative as the original (in case the OP cannot share the original data), it is good to add some information with the data example as (if we call the data mydf1)
class(mydf1)
# this shows the type of the data you have
dim(mydf1)
# this shows the dimension of your data
Moreover, one should know the type, length and attributes of a data which can be Data structures
#found based on the following
typeof(mydf1), what it is.
length(mydf1), how many elements it contains.
attributes(mydf1), additional arbitrary metadata.
#If you cannot share your original data, you can str it and give an idea about the structure of your data
head(str(mydf1))
Here are some of my suggestions:
dput
install.package()
require
library
Try to be concise,
All these are part of a reproducible example.
You haven't really added anything of substance here.
dput()
has been mentioned previously, and much of this is just reiterating standard SO guidelines.– Rich Scriven
Apr 9 '16 at 19:04
dput()
I was having problem with
install.package
function included in the example which is not really necessary (in my opinion). Further, using default R dataset would make the reproducible easier. The SO guidelines has not talked anything about these topics specifically. Further, It was meant to give my opinion and these are the one which I have encountered most.– TheRimalaya
Apr 9 '16 at 19:17
install.package
You can do this using reprex.
As mt1022 noted, "... good package for producing minimal, reproducible example is "reprex" from tidyverse".
According to Tidyverse:
The goal of "reprex" is to package your problematic code in such a way that other people can run it and feel your pain.
An example is given on tidyverse web site.
library(reprex)
y <- 1:4
mean(y)
reprex()
I think this is the simplest way to create a reproducible example.
It's a good idea to use functions from the testthat
package to show what you expect to occur. Thus, other people can alter your code until it runs without error. This eases the burden of those who would like to help you, because it means they don't have to decode your textual description. For example
testthat
library(testthat)
# code defining x and y
if (y >= 10)
expect_equal(x, 1.23)
else
expect_equal(x, 3.21)
is clearer than "I think x would come out to be 1.23 for y equal to or exceeding 10, and 3.21 otherwise, but I got neither result". Even in this silly example, I think the code is clearer than the words. Using testthat
lets your helper focus on the code, which saves time, and it provides a way for them to know they have solved your problem, before they post it
testthat
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
I'm confused about the scope of the question. People seem to have jumped on the interpretation of reproducible example in asking questions on SO or R-help (how to "reproduce the error"). What about reproducible R examples in help pages? In package demos? In tutorials / presentations?
– baptiste
Aug 7 '11 at 2:14