knitr::opts_chunk$set( warning = FALSE, collapse = TRUE, comment = "#>" ) options(str = strOptions(vec.len = 9)) library(plume) library(readr) library(gt)
The goal of the plume package is to make the handling and formatting of author data for scientific writing in R Markdown and Quarto easy and painless.
We'll use the data sets encyclopedists
and encyclopedists_fr
to explore the different functionalities of the package. These data sets contain information on four famous authors of the "Encyclopédie", published in France in the 18th century. encyclopedists_fr
is the French translation of encyclopedists
and will be used to illustrate how to handle custom variable names. Both data sets are documented in ?encyclopedists
.
encyclopedists
plume
objectplume provides two R6 classes, namely Plume
and PlumeQuarto
. To create a plume
object, simply write the name of the class you want to use followed by the new()
method. plume classes take a data frame or tibble as input data. The input data must have at least two columns, one for given names and another for family names.
Plume$new(encyclopedists)
list_keys <- function(x) { nms <- names(x) out <- vector("list", length(x)) for (i in seq_along(x)) { x_i <- x[[i]] if (is.list(x_i)) { out[[i]] <- list_keys(x_i) } else { out[[i]] <- nms[i] } } unlist(out) } build_table <- function(data) { gt(data) |> text_case_match( "TRUE" ~ fontawesome::fa("check"), .default = "", .locations = cells_body(tidyselect::starts_with("Plume")) ) |> cols_label(name = "Name") |> cols_align(align = "center", columns = tidyselect::starts_with("Plume")) |> cols_width(name ~ pct(50)) |> opt_row_striping() } fetch <- plume:::list_fetch .names_plume <- plume:::.names_plume .names_quarto <- plume:::.names_quarto .names_all <- purrr::list_modify(.names_plume, !!!.names_quarto) are_within <- function(x, y) { unlist(y) %in% unlist(x) } make_table_vars <- function(category) { vars_plume <- fetch(.names_plume, category) vars_plume_quarto <- fetch(.names_quarto, category) vars <- fetch(.names_all, category) build_table(tibble::tibble( name = list_keys(vars), Plume = are_within(vars_plume, vars), PlumeQuarto = are_within(vars_plume_quarto, vars), )) }
The default variables handled by plume classes are organised into six categories:
Primaries: variables required to create a plume
object.
make_table_vars("primaries")
Secondaries: optional variables that can be provided in the input data.
make_table_vars("secondaries")
Nestables: optional variables that can be provided in the input data to pass multiple independent values to authors. Nestable variables must start with the same prefix. E.g. affiliation_1
, affiliation_2
, ..., affiliation_n
to pass several affiliations to authors.
make_table_vars("nestables")
Constants: optional names that can be provided in the input data. These names are standardised and must be provided as is.
make_table_vars("protected")
Internals: variables created internally. These variables don't need to be provided in the input data and are ignored if supplied. You shouldn't worry much about these variables unless you want to customise names or extend plume classes with new default names.
make_table_vars("internals")
Meta: PlumeQuarto
-specific variables used to pass extra information that doesn't fit in other categories. Meta columns must start with the prefix meta-
and are followed by a custom name (e.g. meta-custom_name
). You should only use these variables to pass data that are template specific. See Quarto's arbitrary-metadata section for details.
plume lets you use custom variable names. Simply provide the names
parameter a named vector when instantiating a plume class, where keys are default names and values their respective replacements.
Plume$new( encyclopedists_fr, names = c( given_name = "prénom", family_name = "nom", literal_name = "nom_complet", email = "courriel", initials = "initiales" ) )
You can add roles by creating specific role columns in the input data and indicate contributors using 1
:
tibble::tibble( given_name = c("Denis", "Jean-Jacques", "François-Marie", "Jean"), family_name = c("Diderot", "Rousseau", "Arouet", "Le Rond d'Alembert"), supervision = c(1, NA, NA, 1), writing = 1, )
plume uses the r plume:::link("crt")
(CRediT) by default (assuming the input data contains the appropriate columns). You can specify your own roles via the roles
parameter when creating a plume
object. The roles
parameter takes a vector of key-value pairs where keys identify role columns and values define the actual roles to use.
Plume$new(data, roles = c( supervision = "supervised the project", writing = "contributed to the writing" ))
status_methods <- tibble::tibble( name = c( "set_corresponding_authors()", "set_main_contributors()", "set_cofirst_authors()", "set_deceased()" ), Plume = as.logical(c(1, 1, 0, 0)), PlumeQuarto = as.logical(c(1, 0, 1, 1)), )
plume provides r nrow(status_methods)
methods to set particular status to authors:
build_table(status_methods)
By default, set_*()
methods assign values by authors' id. You can change this behaviour at the object or method level using the by
/.by
parameters.
Note that these methods are case insensitive.
aut <- Plume$new(dplyr::select(encyclopedists, given_name, family_name)) aut$set_corresponding_authors(dd, "j-jr", .by = "initials") aut
Use everyone()
to assign TRUE
to all authors:
aut$set_corresponding_authors(everyone()) aut
PlumeQuarto
allows you to inject author metadata directly into YAML files or the YAML header of .qmd
files.
Consider the following Quarto document:
tmp_file <- withr::local_tempfile( lines = "---\ntitle: Encyclopédie\n---\n\nQui scribit bis legit", fileext = ".qmd" )
cat(read_file(tmp_file))
You can push information from the input data into the YAML or Quarto file using the to_yaml()
method:
aut <- PlumeQuarto$new( dplyr::slice(encyclopedists, 1, 4), file = "file.qmd" ) aut$to_yaml()
aut <- PlumeQuarto$new(dplyr::slice(encyclopedists, 1, 4), tmp_file) aut$to_yaml() cat(read_file(tmp_file))
Authors are listed in the order they're defined in the input data.
If the YAML or Quarto file already has an author
and affiliations
keys, to_yaml()
replaces old values with new ones.
aut <- PlumeQuarto$new( dplyr::slice(encyclopedists, 2), file = "file.qmd" ) aut$to_yaml()
aut <- PlumeQuarto$new(dplyr::slice(encyclopedists, 2), tmp_file) aut$to_yaml() cat(read_file(tmp_file))
get_*()
methods (available through the Plume
class) format author information as character vectors. This is useful if you want to output author data in a document without using journal templates.
get_author_list()
generates author lists. You can control the formatting of author suffixes (symbols linking authors to affiliations, notes and other metadata) using the suffix
parameter. suffix
takes a character string as argument and allows you to choose which symbol categories to suffix authors with, using the following keys:
a
for affiliations
c
for corresponding authors
n
for notes
o
for ORCIDs
The order of the keys determines the order of symbol categories.
aut <- Plume$new(encyclopedists) aut$set_corresponding_authors(everyone()) aut$get_author_list(suffix = "ac") aut$get_author_list(suffix = "ca")
In addition, you can use ^
to superscript and ,
to separate symbols:
aut$set_corresponding_authors(1, 4) aut$get_author_list("^a,^cn")
Use suffix = NULL
or suffix = ""
to ignore suffixes:
aut$get_author_list(suffix = NULL)
get_affiliations()
and get_notes()
return authors' affiliations and notes.
aut$get_affiliations() aut$get_notes(sep = ": ", superscript = FALSE)
get_orcids()
returns authors with their respective ORCID.
aut$get_orcids(icon = FALSE, sep = " ")
You can get contact details of corresponding authors using the get_contact_details()
method:
aut$get_contact_details() aut$get_contact_details(phone = TRUE) aut$get_contact_details(format = "{name}: {details}")
plume provides a convenient way to generate contribution lists using the get_contributions()
method.
aut$get_contributions() aut$get_contributions( roles_first = FALSE, by_author = TRUE, literal_names = TRUE ) aut2 <- Plume$new(encyclopedists, roles = c( supervision = "supervised the project", writing = "contributed to the Encyclopédie" )) aut2$get_contributions(roles_first = FALSE, divider = " ")
By default, get_contributions()
lists contributors in the order they're defined. You can arrange contributors in alphabetical order with alphabetical_order = TRUE
:
aut$get_contributions(alphabetical_order = TRUE)
It's possible to force one or more contributors to appear first in any given role by setting main contributors:
aut$set_main_contributors(supervision = 4, writing = c(3, 2)) aut$get_contributions()
You can assign the same main contributors across multiple roles using the .roles
parameter. E.g. to set a main contributor across all roles:
aut$set_main_contributors(jean, .roles = aut$get_roles(), .by = "given_name") aut$get_contributions()
Note that main contributors have the priority over the alphabetical ordering:
aut$get_contributions(alphabetical_order = TRUE)
The .roles
parameter only applies to unnamed expressions. This allows you to set the same main contributors across all but a few specific roles at once.
aut$set_main_contributors(4, 3, supervision = 1, .roles = aut$get_roles())
Here, authors 4 and 3 are the main contributors in all roles but supervision
, where author 1 is the main contributor.
Default symbols are:
str(plume:::.symbols)
You can change symbols when creating a plume
object using the parameter symbols
.
Use NULL
to display numbers:
aut <- Plume$new( encyclopedists, symbols = list(affiliation = letters, note = NULL) ) aut$get_author_list("^a,n^")
Use NULL
as much as possible for symbols using numerous unique items (typically affiliations). If you have to use letters for a given category that has more unique items than letters, you can control the sequencing behaviour using the sequential()
modifier, as shown below:
Plume$new( encyclopedists, symbols = list(affiliation = sequential(letters)) )
By default, plume repeats elements when all elements in a vector are consumed. Using sequential()
allows you to display a logical sequence of characters (e.g. a, b, c, ..., z, aa, ab, ac, ..., az, ba, bb, bc, ...
).
To output author data as markdown content, use the chunk option results: asis
in combination with cat()
:
```r #| results: asis aut$get_contributions() |> cat(sep = "; ") ```
Inline chunks output values "as is" by default and can be used as follows:
`r knitr::inline_expr("aut$get_author_list()")`
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.