# Reprex do’s and don’ts

If you’re asking for R help, reporting a bug, or requesting a new feature, you’re more likely to succeed if you include a good reprex.

## Main requirements

Use the smallest, simplest, most built-in data possible.

- Think: `iris` or `mtcars`. Bore me.
- If you must make some objects, minimize their size and complexity.
- Many of the functions and packages you already use to import data from delimited files also offer a way to create a small data frame “inline”:
  - `read.table()` and friends have a `text` argument. Example: `read.csv(text = "a,b\n1,2\n3,4")`.

  - `tibble::tribble()` lets you use a natural and readable layout. Example:

          tibble::tribble(
            ~ a, ~ b,
              1,   2,
              3,   4
          )
          #> # A tibble: 2 x 2
          #>       a     b
          #>   <dbl> <dbl>
          #> 1     1     2
          #> 2     3     4

- Get just a bit of something with `head()` or by indexing with the result of `sample()`. If anything is random, consider using `set.seed()` to make it repeatable.
- `dput()` is a good way to get the code to create an object you have lying around, if you simply cannot make do with built-in or simulated data. Copy and paste the result of this into your reprex.
- Look at official examples and try to write in that style. Consider adapting one.

Include commands on a strict “need to run” basis.

- Ruthlessly strip out anything unrelated to the specific matter at hand.
- Include every single command that is required, e.g. loading specific packages via `library(foo)`.

Consider including so-called “session info”, i.e. your OS and versions of R and add-on packages, if it’s conceivable that it matters.

- Use `reprex(..., si = TRUE)` for this.

Whitespace rationing is not in effect.

- Use good coding style.
- Use `reprex(..., style = TRUE)` to request automated styling of your code.

Pack it in, pack it out, and don’t take liberties with other people’s computers. You are asking people to run this code!

- Don’t start with `rm(list = ls())`. It is anti-social to clobber other people’s workspaces.
- Don’t start with `setwd("C:\Users\jenny\path\that\only\I\have")`, because it won’t work on anyone else’s computer.
- Don’t mask built-in functions, i.e. don’t define a new function named `c` or `mean`.

- If you change options, store original values at the start, do your thing, then restore them:

      opar <- par(pch = 19)
      <blah blah blah>
      par(opar)

- If you create files, delete them when you’re done:

      write(x, "foo.txt")
      <blah blah blah>
      file.remove("foo.txt")

- Don’t delete files or objects that you didn’t create in the first place.

- Take advantage of R’s built-in ability to create temporary files and directories. Read up on `tempfile()` and `tempdir()`.

## This seems like a lot of work!

Yes, creating a great reprex requires work. You are asking other people to do work too. It’s a partnership.

80% of the time you will solve your own problem in the course of writing an excellent reprex. YMMV.

The remaining 20% of the time, you will create a reprex that is more likely to elicit the desired behavior in others.

## Further reading:

How to make a great R reproducible example? thread on StackOverflow

How to write a reproducible example from Hadley Wickham’s Advanced R book

## Package philosophy

The reprex code:

- Must run and, therefore, should be run by the person posting. No faking it.

- Should be easy for others to digest, so they don’t necessarily have to run it. You are encouraged to include selected bits of output. :scream:

- Should be easy for others to copy + paste + run, if and only if they so choose. Don’t let inclusion of output break executability.

Accomplished like so:

- Use `rmarkdown::render()` to run the code and capture output that you would normally see on your screen. This is done in a separate R process, via callr, to guarantee it is self-contained.

- Use chunk option `comment = "#>"` to include the output while retaining executability.

## Other work

If I had known about `formatR::tidy_eval()`, I probably would never had made reprex! But alas I did not. AFAICT here are the main differences:

- `reprex()` accepts an expression as primary input, in addition to code on the clipboard, in a character vector, or in a file.
- `reprex()` runs the reprex in a separate R process, via callr. `tidy_eval()` uses the existing R process and offers an `envir` argument.
- `reprex()` writes the code to a `.R` file and calls `rmarkdown::render()`. `tidy_eval()` runs the code line-by-line via `capture.output(eval(..., envir = envir))`.
- `reprex()` uploads figures to imgur and inserts the necessary link.