Table Hierarchy
Abinaya Yogasekaram
2024-12-20
Source:vignettes/dev-guide/dg_table_hierarchy.Rmd
dg_table_hierarchy.Rmd
Disclaimer
This article is intended for use by developers only and will contain
low-level explanations of the topics covered. For user-friendly
vignettes, please see the Articles
page on the rtables
website.
Any code or prose which appears in the version of this article on the
main
branch of the repository may reflect a specific state
of things that can be more or less recent. This guide describes very
important aspects of table hierarchy that are unlikely to change.
Regardless, we invite the reader to keep in mind that the current
repository code may have drifted from the following material in this
document, and it is always the best practice to read the code directly
on main
.
Please keep in mind that rtables
is still under active
development, and it has seen the efforts of multiple contributors across
different years. Therefore, there may be legacy mechanisms and ongoing
transformations that could look different in the future.
Introduction
The scope of this vignette is to understand the structure of
rtable
objects, class hierarchy with an exploration of tree
structures as S4 objects. Exploring table structure enables a better
understanding of rtables
concepts such as split machinery,
tabulation, pagination and export. More details from the user’s
perspective of table structure can be found in the relevant
vignettes.
isS4
getclass
- for class structure
Process and Methods
We invite developers to use the provided examples to interactively
explore the rtables
hierarchy. The most helpful command is
getClass
for a list of the slots associated with a class,
in addition to related classes and their relative distances.
Table Representation
PredataAxisLayout
class is used to define the data
subset instructions for tabulation. 2 sub-classes (one for each axis):
PredataColLayout
, PredataRowLayout
Content (summary row groups)
Splits are core functionality for rtables
as tabulation
and calculations are often required on subsets of the data.
Split Machinery
## Class "TreePos" [package "rtables"]
##
## Slots:
##
## Name: splits s_values sval_labels subset
## Class: list list character SubsetDef
TreePos
class contains split information as a list of
the splits, split label values, and the subsets of the data that are
generated by the split.
AllSplit
RootSplit
MultiVarSplit
VarStaticCutSplit
CumulativeCutSplit
VarDynCutSplit
CompoundSplit
VarLevWBaselineSplit
The highest level of the table hierarchy belong to
TableTree
. The code below identifies the slots associated
with with this class.
getClass("TableTree")
## Class "TableTree" [package "rtables"]
##
## Slots:
##
## Name: content page_title_prefix children
## Class: ElementaryTable character list
##
## Name: rowspans labelrow page_titles
## Class: data.frame LabelRow character
##
## Name: horizontal_sep header_section_div trailing_section_div
## Class: character character character
##
## Name: col_info format na_str
## Class: InstantiatedColumnInfo FormatSpec character
##
## Name: indent_modifier table_inset level
## Class: integer integer integer
##
## Name: name main_title subtitles
## Class: character character character
##
## Name: main_footer provenance_footer
## Class: character character
##
## Extends:
## Class "VTableTree", directly
## Class "VTableNodeInfo", by class "VTableTree", distance 2
## Class "VTree", by class "VTableTree", distance 2
## Class "VTitleFooter", by class "VTableTree", distance 2
## Class "VNodeInfo", by class "VTableTree", distance 3
As an S4 object, the slots can be accessed using @
(similar to the use of $
for list objects). You’ll notice
there are classes that fall under “Extends”. The classes contained here
have a relationship to the TableTree
object and are
“virtual” classes. To avoid the repetition of slots and carrying the
same data (set of slots for example) that multiple classes may need,
rtables
extensively uses virtual classes. A virtual class
cannot be instantiated, the purpose is for other classes to inherit
information from it.
lyt <- basic_table(title = "big title") %>%
split_rows_by("SEX", page_by = TRUE) %>%
analyze("AGE")
tt <- build_table(lyt, DM)
# Though we don't recommend using str for studying rtable objects,
# we do find it useful in this instance to visualize the parent/child relationships.
str(tt, max.level = 2)
## Formal class 'TableTree' [package "rtables"] with 20 slots
## ..@ content :Formal class 'ElementaryTable' [package "rtables"] with 19 slots
## ..@ page_title_prefix : chr "SEX"
## ..@ children :List of 4
## ..@ rowspans :'data.frame': 0 obs. of 0 variables
## ..@ labelrow :Formal class 'LabelRow' [package "rtables"] with 13 slots
## ..@ page_titles : chr(0)
## ..@ horizontal_sep : chr "—"
## ..@ header_section_div : chr NA
## ..@ trailing_section_div: chr NA
## ..@ col_info :Formal class 'InstantiatedColumnInfo' [package "rtables"] with 9 slots
## ..@ format : NULL
## ..@ na_str : chr NA
## ..@ indent_modifier : int 0
## ..@ table_inset : int 0
## ..@ level : int 1
## ..@ name : chr "SEX"
## ..@ main_title : chr "big title"
## ..@ subtitles : chr(0)
## ..@ main_footer : chr(0)
## ..@ provenance_footer : chr(0)
## Warning: str provides a low level, implementation-detail-specific description
## of the TableTree object structure. See table_structure(.) for a summary of
## table struture intended for end users.
Tree Paths
Root to Leaves, are vectors of vectors Tables are tree, nodes in the tree can have summaries associated with them. Tables are trees because of the nested structure. There is also the benefit of keeping and repeating necessary information when trying to paginate a table.
Children of ElementaryTables
are row objects.
TableTree
can have children that are either row objects or
other table objects.