R offers several object‑oriented systems (S3, S4, R6), and S7 is the most recent addition: a modern, lightweight, and more predictable approach to defining classes and methods. For statistical workflows—especially those involving complex design objects, parameter grids, and multi‑software comparisons—S7 brings a clean and explicit structure. In this post, I walk through how I use S7 to define two core objects in my sample‑size comparison pipeline:
ssc_design: represents a study design (endpoint, type, parameters, computation rules).
ssc_results: stores the associated sample size results produced by different software tools.
The constructor controls how a ssc_design object is created and restricts the possible argument values.
We also want to enforce consistency rules. For example:
Binary endpoints must specify a computation method.
Survival endpoints must not specify a computation method.
The params list must contain at least $list and $table.
Validator
We encode these rules in a validator:
Code
validator =function(self) {if (self@endpoint =="binary") {if (length(self@computation) ==0||!(self@computation %in%c("exact", "pooled", "unpooled")) ) {"@computation should be one of exact, pooled or unpooled." } } elseif (length(self@computation) !=0) {"@computation should be NULL for survival endpoint" } elseif (length(self@params$list) ==0||length(self@params$table) ==0) {"@params should contains at least $list and $table." }}
The validator is automatically executed when building a ssc_design object, if the object violates any rule, an error is returned.
Example: the following call triggers a validation error because "poled" is not a valid computation method:
Error:
! <ssc_design> object is invalid:
- @computation should be one of exact, pooled or unpooled.
Methods
A main benefit of defining classes is that you can attach methods to them.
Below, we create a print method for ssc_design. We also create a helper method show_params():
The validator uses the design’s parameter table to ensure:
the number of results does not exceed the number of parameter combinations,
there are no duplicated parameter sets,
all parameter combinations in the results appear in the design’s parameter grid.
Code
# VALIDATORvalidator <-function(self) {if (nrow(self@tbl) >nrow(self@design@params$table)) {return("@tbl has too many rows according to the parameters.") } params_names <-names(self@design@params$list) cond_duplicate <- self@tbl |>select(all_of(params_names)) |>duplicated() |>any()if (cond_duplicate) {return("@tbl should not contain any duplicate of input combinations.") } cond_in_params <- self@tbl |>anti_join(self@design@params$table, by = params_names) |>nrow()if (cond_in_params >0) {return("@tbl should not contain combinations not present in @params$table.") }return(NULL)}
Methods
We can now instantiate and inspect a results object:
── SSC rpact results for binary fixed design ──
alpha power pi_c delta_pi n
Min. :0.01 Min. :0.5100 Min. :0.1000 Min. :0.0500 Min. : 2.0
1st Qu.:0.05 1st Qu.:0.7275 1st Qu.:0.1000 1st Qu.:0.0500 1st Qu.: 54.0
Median :0.10 Median :0.8500 Median :0.3000 Median :0.1500 Median : 192.5
Mean :0.17 Mean :0.8000 Mean :0.4067 Mean :0.2047 Mean : 832.8
3rd Qu.:0.20 3rd Qu.:0.9225 3rd Qu.:0.5000 3rd Qu.:0.2500 3rd Qu.: 875.8
Max. :0.49 Max. :0.9900 Max. :0.9000 Max. :0.4900 Max. :9578.0
Display the design parameters directly from the results object:
Code
show_params(rpact_results)
Code
Moving parameters:
alpha: 0.01, 0.05, 0.1, 0.2 and 0.49
power: 0.51, 0.8, 0.9 and 0.99
pi_c: 0.1, 0.3, 0.5, 0.8 and 0.9
delta_pi: 0.05, 0.15, 0.25 and 0.49
Additional parameters:
sided: 2
Number of parameters combinaisons:
[1] 30