Structured lists are a simple(r) and lighter weight alternative to
vctrs
from the tidyverse
package. In
pkgutils
a struct
is defined as a S3 class
based on a named list of values that is managed as a single entity. E.g.
a value and confidence limits. All struct
s live in
struct_list
s allowing them to be part of data frames. This
list of S3 classes/lists approach means that struct
s need
infrastructure to make sure they stay in the same format.
The aim of struct_list
is to be transparent to the user
and created in a package, but removing the overhead of managing data as
lists of lists.
Constructor
As with vctrs
the first step is to define a constructor
function that performs any error checking, and handles any vectorisation
needed
new_HR = function(mid, lower, upper, p.value) {
return(struct(
mid = mid,
lower = lower,
upper = upper,
p.value = p.value,
.class = "HR"))
}
format.HR = function(x, ...) {
sprintf("%1.2f [%1.2f \u2014 %1.2f] (P:%s)",x$mid,x$lower,x$upper,scales::pvalue(x$p.value))
}
new_HR(1.2,0.8,1.6,0.8534)
#> HR(mid, lower, upper, p.value)
#> 1.20 [0.80 — 1.60] (P:0.853)
Printing as a list of custom S3 object is handled by default using
tibble
and pillar
packages.
df = tibble::tibble(
index = 1:5,
HR = rep(new_HR(1.2,0.8,1.6,0.8534),5)
)
format(df)
#> [1] "\033[38;5;246m# A tibble: 5 × 2\033[39m"
#> [2] " index HR"
#> [3] " \033[3m\033[38;5;246m<int>\033[39m\033[23m \033[3m\033[38;5;246m<HR[]>\033[39m\033[23m"
#> [4] "\033[38;5;250m1\033[39m 1 1.20 [0.80 — 1.60] (P:0.853)"
#> [5] "\033[38;5;250m2\033[39m 2 1.20 [0.80 — 1.60] (P:0.853)"
#> [6] "\033[38;5;250m3\033[39m 3 1.20 [0.80 — 1.60] (P:0.853)"
#> [7] "\033[38;5;250m4\033[39m 4 1.20 [0.80 — 1.60] (P:0.853)"
#> [8] "\033[38;5;250m5\033[39m 5 1.20 [0.80 — 1.60] (P:0.853)"
and it will also print correctly using knitr
s
default
knitr::kable(df)
index | HR |
---|---|
1 | 1.20 [0.80 — 1.60] (P:0.853) |
2 | 1.20 [0.80 — 1.60] (P:0.853) |
3 | 1.20 [0.80 — 1.60] (P:0.853) |
4 | 1.20 [0.80 — 1.60] (P:0.853) |
5 | 1.20 [0.80 — 1.60] (P:0.853) |
# but not directly with huxtable
# huxtable::hux(df %>% dplyr::mutate(HR = format(HR)))
As first class lists they can be manipulated with purrr
functions, for extracting or manipulating values. If the value we expect
back from a purrr::map is a struct
just like
purrr::map_dbl
and similar functions we use a
pkgutils::map_struct
function.
x = new_HR(1.2,0.8,1.6,0.8534)
x$mid
#> [1] 1.2
df$HR$mid
#> [1] 1.2 1.2 1.2 1.2 1.2