We’re overjoyed to announce the release of reprex 2.0.0. reprex is a package that helps you prepare REPRoducible EXamples to share in places where people talk about code, e.g., on GitHub, on Stack Overflow, and in Slack or email messages.
You can install the current version of reprex from CRAN with1:
install.packages("reprex")
reprex recently had a major release ( version 1.0.0), but we’ve added some big features since then. Specifically, reprex has gotten much, much easier to use on RStudio Server and RStudio Cloud. It’s also easier to specify the working directory, if you must, and reprex plays more nicely with the renv package.
You can see a full list of changes in the release notes.
Use in RStudio Server and RStudio Cloud
By default, reprex accepts a code snippet via the clipboard and also puts the rendered result there, ready to paste into GitHub, Stack Overflow, Slack or an email. Removing friction around reprex input/output is one of the main reasons the package exists.
But when working in RStudio Server or RStudio Cloud, you’re running R (and reprex) in a web browser. For very good security reasons, it’s essentially impossible to access your system clipboard programmatically from R in this context. Luckily, thanks to the rstudioapi package, we can safely control the RStudio IDE. This means we can create a smooth reprex workflow using the current selection, instead of the clipboard.
When
reprex()
is called without any code input, in RStudio Server or Cloud, the default is now to consult the current selection for reprex source. Previously this was only available via the
reprex_selection()
addin. 2 Note that this “current selection” default behaviour propagates to convenience wrappers around
reprex()
, such as
reprex_r()
and
reprex_slack()
.
Once your reprex has been rendered, you see the normal html preview, the file containing the rendered reprex is opened in RStudio, and its contents are selected, ready for you to copy via Cmd/Ctrl + C.
These changes also make the “Render reprex” gadget much more usable in RStudio Server or Cloud. reprex has always technically worked in the browser, but the user experience was pretty disappointing. Hopefully now it is actually pleasant!
Working directory
Ideally, a reprex is entirely self-contained and does not read any local files which, presumably, nobody else has. That’s why, by default,
reprex()
works in an ephemeral directory created in the session temp directory. Run
getwd()
inside
reprex()
:
and you’ll see something like this:
getwd()
#> [1] "/private/tmp/RtmpXrUKXE/reprex-13063117cb6d8-alive-lark"
However, in the real world, sometimes you must read a local data file that you can’t share with the world. You can still at least use
reprex()
to reveal your actual code and results.
This has always been possible, but we’ve reworked some arguments to make this more natural to express:
wd
is a new argument to set the reprex working directoryoutfile
is deprecated, with the existinginput
argument taking over its duties
If we run:
we see the working directory is the directory where the source of this blog post lives:
getwd()
#> [1] "/Users/jenny/rrr/tidyverse.org/content/blog/reprex-2-0-0"
The old way to
reprex()
in current working directory was
reprex(outfile = NA)
, which was not very intuitive.
Another good reason to reprex in a specific working directory is for package development. Just put
devtools::load_all(".")
at the start of your reprex and then you can easily explore a code snippet in the context of an experimental version of the package. This is a nice way to create small, concrete “before vs. after” demos when developing a feature or fixing a bug.
Local .Rprofile
and renv happiness
The reprex working directory has even more significance, when you consider the implications for the callr and renv packages.
reprex()
renders the reprex in a separate, fresh R session using
callr::r()
. We accept this default behaviour from callr:
callr::r(..., user_profile = "project")
which means that callr executes a "project"
-level .Rprofile
, if such a file exists in current working directory.
Most reprexes happen in a temp directory and there will be no such .Rprofile
. But if the user intentionally reprexes in, say, an existing project that has .Rprofile
,
callr::r()
and therefore
reprex()
both honor it. (Remember, this has gotten easier, with
reprex(wd = ".")
.)
This is especially important for users of the
renv package, which uses .Rprofile
to implement a project-specific package library:
In an renv project,
reprex(wd = ".")
renders with respect to the project-specific library.
If you include
renv::snapshot(reprex = TRUE)
in your reprex code, the rendered result will even contain the associated renv lockfile, nicely tucked away as collapsible details.
reprex v2.0.0 introduces a few features around project-specific .Rprofile
:
- We explicitly make sure that the working directory of the
callr::r()
call is the same as the effective working directory of the reprex. - We alert the user that a local
.Rprofile
has been found. - We indicate the usage of a local
.Rprofile
in the rendered reprex.
Adjective-animal
Various changes mean that more users will see reprex filepaths. Therefore, we’ve revised them to be more self-explanatory and human-friendly. When reprex needs to invent a file name, it is now based on a random “adjective-animal” slug. Bring on the angry-hamster
! 3
You actually saw one of these filepaths already, in the output of
reprex(getwd())
:
getwd()
#> [1] "/private/tmp/RtmpXrUKXE/reprex-13063117cb6d8-alive-lark"
Acknowledgements
We thank these folks for contributing to this release through their issues, comments, and pull requests:
@23ava, @jennybc, @kiernann, @krlmlr, @llrs, @MatthieuStigler, @mcanouil, @MilesMcBain, @oharac, and @remlapmot.
-
Another way you might get reprex is by installing the tidyverse meta-package. reprex is one of the packages installed by
install.packages("tidyverse")
, however it is not among the core packages attached bylibrary(tidyverse)
. ↩︎ -
The
reprex_selection()
addin is alive and well! What’s new is that it has become the default behaviour in RStudio Server or Cloud.reprex_selection()
is so handy that many reprex users wire it up to a custom keyboard shortcut, such as Cmd + Shift + R (macOS) or Ctrl + Shift + R (Windows). ↩︎ -
reprex()
draws randomly from a fixed set of adjective-animal slugs generated with the handy ids package. ↩︎