Construct objects with idiomatic R code
Use the constructive package instead of dput() to construct R objects with idiomatic R code for human-readable reproducible examples
Today I discovered the constructive package and the construct() function for creating R objects with idiomatic R code to make human-readable reproducible examples.
Docs & vignettes: https://cynkra.github.io/constructive/
Imagine you want to create a reproducible example and you need to create an object you can share somewhere like StackOverflow. Here let’s take the starwars data that ships with dplyr, and get just the first few rows, and only a few select columns.
library(dplyr)
swpartial <-
starwars |>
head(4) |>
select(name, species, films)
swpartial
This partial dataset has 4 rows, 3 columns, and one of those is a list-column.
# A tibble: 4 × 3
name species films
<chr> <chr> <list>
1 Luke Skywalker Human <chr [5]>
2 C-3PO Droid <chr [6]>
3 R2-D2 Droid <chr [7]>
4 Darth Vader Human <chr [4]>
The built-in dput()
function gives you the code to recreate this object:
dput(swpartial)
But the output is hardly human readable:
structure(list(name = c("Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader"
), species = c("Human", "Droid", "Droid", "Human"), films = list(
c("A New Hope", "The Empire Strikes Back", "Return of the Jedi",
"Revenge of the Sith", "The Force Awakens"), c("A New Hope",
"The Empire Strikes Back", "Return of the Jedi", "The Phantom Menace",
"Attack of the Clones", "Revenge of the Sith"), c("A New Hope",
"The Empire Strikes Back", "Return of the Jedi", "The Phantom Menace",
"Attack of the Clones", "Revenge of the Sith", "The Force Awakens"
), c("A New Hope", "The Empire Strikes Back", "Return of the Jedi",
"Revenge of the Sith"))), row.names = c(NA, -4L), class = c("tbl_df",
"tbl", "data.frame"))
Alternatively, load the constructive package and use the construct()
function:
library(constructive)
construct(swpartial)
The code you’ll get will create an identical object, but it’s much more human readable, and it’s probably what you would actually write out if you were constructing this object manually.
tibble::tibble(
name = c("Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader"),
species = c("Human", "Droid", "Droid", "Human"),
films = list(
c(
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"Revenge of the Sith",
"The Force Awakens"
),
c(
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"The Phantom Menace",
"Attack of the Clones",
"Revenge of the Sith"
),
c(
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"The Phantom Menace",
"Attack of the Clones",
"Revenge of the Sith",
"The Force Awakens"
),
c(
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
"Revenge of the Sith"
)
)
)
There are lots of other features and use cases. See the documentation for details.