diff --git a/main/404.html b/main/404.html index febd9f766..9e935a330 100644 --- a/main/404.html +++ b/main/404.html @@ -32,7 +32,7 @@ rtables - 0.6.5.9012 + 0.6.5.9013
vignettes/advanced_usage.Rmd
advanced_usage.Rmd
vignettes/baseline.Rmd
baseline.Rmd
vignettes/clinical_trials.Rmd
clinical_trials.Rmd
vignettes/custom_appearance.Rmd
custom_appearance.Rmd
Section dividers can be set to ” ” to create a blank line.
@@ -559,18 +552,22 @@ Section Dividers# —————————————————————————————————————————————————————— # Sepal.Length # mean / sd 5.01 (0.35) 5.94 (0.52) 6.59 (0.64) +# # range 1.50 2.10 3.00 # # Sepal.Width # mean / sd 3.43 (0.38) 2.77 (0.31) 2.97 (0.32) +# # range 2.10 1.40 1.60 # # Petal.Length # mean / sd 1.46 (0.17) 4.26 (0.47) 5.55 (0.55) +# # range 0.90 2.10 2.40 # # Petal.Width # mean / sd 0.25 (0.11) 1.33 (0.20) 2.03 (0.27) +# # range 0.50 0.80 1.10
Separation characters can be specified for different row splits. However, only one will be printed if they “pile up” next to each diff --git a/main/articles/dev-guide/dg_debug_rtables.html b/main/articles/dev-guide/dg_debug_rtables.html index 599db0e70..a38c6cea3 100644 --- a/main/articles/dev-guide/dg_debug_rtables.html +++ b/main/articles/dev-guide/dg_debug_rtables.html @@ -34,7 +34,7 @@ rtables - 0.6.5.9012 + 0.6.5.9013
vignettes/dev-guide/dg_debug_rtables.Rmd
dg_debug_rtables.Rmd
vignettes/dev-guide/dg_notes.Rmd
dg_notes.Rmd
This is a collection of notes divided by issues and it is a working +document that will end up being a dev vignette one day.
section_div
Everything in the layout is built over split objects, that reside in +00_tabletrees.R. There section_div is defined +internally in each split object as child_section_div and +assigned to NA_character as default. This needs to be in +all split objects that need to have a separator divisor. Object-wise, +the virtual class Split contains section_div +and it has the following subclasses. I tagged with “X” constructor that +allows for section_div to be assigned to a value different +than NA_character, and “NX” otherwise.
00_tabletrees.R
child_section_div
NA_character
Split
+library(rtables)
library(rtables)
## Loading required package: formatters
## Loading required package: magrittr
## +## Attaching package: 'rtables'
## The following object is masked from 'package:utils': +## +## str
+getClass("Split")
getClass("Split")
## Virtual Class "Split" [package "rtables"] +## +## Slots: +## +## Name: payload name split_label +## Class: ANY character character +## +## Name: split_format split_na_str split_label_position +## Class: FormatSpec character character +## +## Name: content_fun content_format content_na_str +## Class: listOrNULL FormatSpec character +## +## Name: content_var label_children extra_args +## Class: character logical list +## +## Name: indent_modifier content_indent_modifier content_extra_args +## Class: integer integer list +## +## Name: page_title_prefix child_section_div +## Class: character character +## +## Known Subclasses: +## Class "CustomizableSplit", directly +## Class "AllSplit", directly +## Class "VarStaticCutSplit", directly +## Class "VarDynCutSplit", directly +## Class "VAnalyzeSplit", directly +## Class "CompoundSplit", directly +## Class "VarLevelSplit", by class "CustomizableSplit", distance 2 +## Class "MultiVarSplit", by class "CustomizableSplit", distance 2 +## Class "RootSplit", by class "AllSplit", distance 2 +## Class "ManualSplit", by class "AllSplit", distance 2 +## Class "CumulativeCutSplit", by class "VarStaticCutSplit", distance 2 +## Class "AnalyzeVarSplit", by class "VAnalyzeSplit", distance 2 +## Class "AnalyzeColVarSplit", by class "VAnalyzeSplit", distance 2 +## Class "AnalyzeMultiVars", by class "CompoundSplit", distance 2 +## Class "VarLevWBaselineSplit", by class "VarLevelSplit", distance 3
+# Known Subclasses: +#? Class "CustomizableSplit", directly # vclass used for grouping different split types (I guess) +# Class "AllSplit", directly # NX +# Class "VarStaticCutSplit", directly # X via make_static_cut_split +# Class "VarDynCutSplit", directly # X +# Class "VAnalyzeSplit", directly # X +#? Class "CompoundSplit", directly # Used only for AnalyzeMultiVars (maybe not needed?) +# Class "VarLevelSplit", by class "CustomizableSplit", distance 2 # X +# Class "MultiVarSplit", by class "CustomizableSplit", distance 2 # X +# Class "RootSplit", by class "AllSplit", distance 2 # NX +# Class "ManualSplit", by class "AllSplit", distance 2 # X +# Class "CumulativeCutSplit", by class "VarStaticCutSplit", distance 2 # X via make_static_cut_split +# Class "AnalyzeVarSplit", by class "VAnalyzeSplit", distance 2 # Virtual +# Class "AnalyzeColVarSplit", by class "VAnalyzeSplit", distance 2 # X +# Class "AnalyzeMultiVars", by class "CompoundSplit", distance 2 # X +# Class "VarLevWBaselineSplit", by class "VarLevelSplit", distance 3 # NX
# Known Subclasses: +#? Class "CustomizableSplit", directly # vclass used for grouping different split types (I guess) +# Class "AllSplit", directly # NX +# Class "VarStaticCutSplit", directly # X via make_static_cut_split +# Class "VarDynCutSplit", directly # X +# Class "VAnalyzeSplit", directly # X +#? Class "CompoundSplit", directly # Used only for AnalyzeMultiVars (maybe not needed?) +# Class "VarLevelSplit", by class "CustomizableSplit", distance 2 # X +# Class "MultiVarSplit", by class "CustomizableSplit", distance 2 # X +# Class "RootSplit", by class "AllSplit", distance 2 # NX +# Class "ManualSplit", by class "AllSplit", distance 2 # X +# Class "CumulativeCutSplit", by class "VarStaticCutSplit", distance 2 # X via make_static_cut_split +# Class "AnalyzeVarSplit", by class "VAnalyzeSplit", distance 2 # Virtual +# Class "AnalyzeColVarSplit", by class "VAnalyzeSplit", distance 2 # X +# Class "AnalyzeMultiVars", by class "CompoundSplit", distance 2 # X +# Class "VarLevWBaselineSplit", by class "VarLevelSplit", distance 3 # NX
This can be updated only by related layout functions. The most +important, that are covered by tests are analyze and +split_rows_by.
analyze
split_rows_by
Now it is relevant to understand where this information is saved in +the table object built by build_table. To do that we need +to see where it is present and how it is assigned. Let’s go back to +00tabletree.Rand look for +trailing_section_div. As classes definitions goes, you will +notice from the search that trailing_section_div is present +in the virtual classes TableRow and +VTableTree. In the following is the class hierarchy that +makes `trailing_section_div:
build_table
00tabletree.R
trailing_section_div
TableRow
VTableTree
+getClass("TableRow")
getClass("TableRow")
## Virtual Class "TableRow" [package "rtables"] +## +## Slots: +## +## Name: leaf_value var_analyzed label +## Class: ANY character character +## +## Name: row_footnotes trailing_section_div level +## Class: list character integer +## +## Name: name col_info format +## Class: character InstantiatedColumnInfo FormatSpec +## +## Name: na_str indent_modifier table_inset +## Class: character integer integer +## +## Extends: +## Class "VLeaf", directly +## Class "VTableNodeInfo", directly +## Class "VNodeInfo", by class "VLeaf", distance 2 +## +## Known Subclasses: "DataRow", "ContentRow", "LabelRow"
+# Extends: +# Class "VLeaf", directly +# Class "VTableNodeInfo", directly +# Class "VNodeInfo", by class "VLeaf", distance 2 +# +# Known Subclasses: "DataRow", "ContentRow", "LabelRow" + +getClass("VTableTree")
# Extends: +# Class "VLeaf", directly +# Class "VTableNodeInfo", directly +# Class "VNodeInfo", by class "VLeaf", distance 2 +# +# Known Subclasses: "DataRow", "ContentRow", "LabelRow" + +getClass("VTableTree")
## Virtual Class "VTableTree" [package "rtables"] +## +## Slots: +## +## Name: children rowspans labelrow +## Class: list data.frame LabelRow +## +## Name: page_titles horizontal_sep header_section_div +## Class: character character character +## +## Name: trailing_section_div col_info format +## Class: character InstantiatedColumnInfo FormatSpec +## +## Name: na_str indent_modifier table_inset +## Class: character integer integer +## +## Name: level name main_title +## Class: integer character character +## +## Name: subtitles main_footer provenance_footer +## Class: character character character +## +## Extends: +## Class "VTableNodeInfo", directly +## Class "VTree", directly +## Class "VTitleFooter", directly +## Class "VNodeInfo", by class "VTableNodeInfo", distance 2 +## +## Known Subclasses: "ElementaryTable", "TableTree"
+# Extends: +# Class "VTableNodeInfo", directly +# Class "VTree", directly +# Class "VTitleFooter", directly +# Class "VNodeInfo", by class "VTableNodeInfo", distance 2 +# +# Known Subclasses: "ElementaryTable", "TableTree"
# Extends: +# Class "VTableNodeInfo", directly +# Class "VTree", directly +# Class "VTitleFooter", directly +# Class "VNodeInfo", by class "VTableNodeInfo", distance 2 +# +# Known Subclasses: "ElementaryTable", "TableTree"
Always check the constructors after finding the classes. In the above +case for example, the DataRow and ContentRow +share the constructor, so we do not need to add identical getter and +setters for these two classes but only for the virtual class +TableRow. Different is the story for LabelRow +which needs to be handle differently. Now, to understand why only these +two have this feature, lets see the structure of a table built with +section dividers:
DataRow
ContentRow
LabelRow
+lyt <- basic_table() %>% + split_rows_by("ARM", section_div = "+") %>% + split_rows_by("STRATA1", section_div = "") %>% + analyze("AGE", + afun = function(x) list("Mean" = mean(x), "Standard deviation" = sd(x)), + format = list("Mean" = "xx.", "Standard deviation" = "xx."), + section_div = "~") + +tbl <- build_table(lyt, DM) + +print(tbl)
lyt <- basic_table() %>% + split_rows_by("ARM", section_div = "+") %>% + split_rows_by("STRATA1", section_div = "") %>% + analyze("AGE", + afun = function(x) list("Mean" = mean(x), "Standard deviation" = sd(x)), + format = list("Mean" = "xx.", "Standard deviation" = "xx."), + section_div = "~") + +tbl <- build_table(lyt, DM) + +print(tbl)
## all obs +## ———————————————————————————————— +## A: Drug X +## A +## Mean 33 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 7 +## +## B +## Mean 35 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 7 +## +## C +## Mean 36 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 9 +## ++++++++++++++++++++++++++++++++ +## B: Placebo +## A +## Mean 32 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 6 +## +## B +## Mean 32 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 6 +## +## C +## Mean 34 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 7 +## ++++++++++++++++++++++++++++++++ +## C: Combination +## A +## Mean 36 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 7 +## +## B +## Mean 34 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 6 +## +## C +## Mean 34 +## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## Standard deviation 6
+print(class(tbl)) # TableTree
print(class(tbl)) # TableTree
## [1] "TableTree" +## attr(,"package") +## [1] "rtables"
+# methods("trailing_section_div") # to see this please do devtools::load_all() +# [1] trailing_section_div,LabelRow-method +# trailing_section_div,TableRow-method +# trailing_section_div,VTableTree-method
# methods("trailing_section_div") # to see this please do devtools::load_all() +# [1] trailing_section_div,LabelRow-method +# trailing_section_div,TableRow-method +# trailing_section_div,VTableTree-method
In the above, we show that trailing_section_div has +methods for TableRow virtual object, LabelRow, +and VTableTree. These three make the whole +section_div structure as the VTableTree is +present in TableTree and ElementaryTable that +are the two main table objects. If these are not +NA_character_ then the section_div is printed +at split divisions. The LabelRow and TableRow +are different as their assignment allows the row-wise modification of +separators. When we have a special case for a ContentRow, +as it is represented as content_table(obj) which is a +one-line ElementaryTable, while label row is turned off. +Please take a moment to check the following setter:
TableTree
ElementaryTable
NA_character_
content_table(obj)
+setMethod("section_div<-", "VTableTree", function(obj, value, only_sep_sections = FALSE) { + char_v <- as.character(value) + tree_depths <- unname(vapply(collect_leaves(obj), tt_level, numeric(1))) + max_tree_depth <- max(tree_depths) + stopifnot(is.logical(only_sep_sections)) + .check_char_vector_for_section_div(char_v, max_tree_depth, nrow(obj)) + + # Automatic establishment of intent + if (length(char_v) < nrow(obj)) { + only_sep_sections <- TRUE + } + + # Case where only separators or splits need to change externally + if (only_sep_sections && length(char_v) < nrow(obj)) { + if (length(char_v) == 1) { + char_v <- rep(char_v, max_tree_depth - 1) # -1 is the data row + } + # Case where char_v is longer than the max depth + char_v <- char_v[seq_len(min(max_tree_depth, length(char_v)))] + # Filling up with NAs the rest of the tree depth section div chr vector + missing_char_v_len <- max_tree_depth - length(char_v) + char_v <- c(char_v, rep(NA_character_, missing_char_v_len)) + # char_v <- unlist( + # lapply(tree_depths, function(tree_depth_i) char_v[seq_len(tree_depth_i)]), + # use.names = FALSE + # ) + } + + # Retrieving if it is a contentRow (no need for labelrow to be visible in this case) + content_row_tbl <- content_table(obj) + is_content_table <- isS4(content_row_tbl) && nrow(content_row_tbl) > 0 + + # Main table structure change + if (labelrow_visible(obj) || is_content_table) { + if (only_sep_sections) { + # Only tables are modified + trailing_section_div(tt_labelrow(obj)) <- NA_character_ + trailing_section_div(obj) <- char_v[1] + section_div(tree_children(obj), only_sep_sections = only_sep_sections) <- char_v[-1] + } else { + # All leaves are modified + trailing_section_div(tt_labelrow(obj)) <- char_v[1] + trailing_section_div(obj) <- NA_character_ + section_div(tree_children(obj), only_sep_sections = only_sep_sections) <- char_v[-1] + } + } else { + section_div(tree_children(obj), only_sep_sections = only_sep_sections) <- char_v + } + obj +})
setMethod("section_div<-", "VTableTree", function(obj, value, only_sep_sections = FALSE) { + char_v <- as.character(value) + tree_depths <- unname(vapply(collect_leaves(obj), tt_level, numeric(1))) + max_tree_depth <- max(tree_depths) + stopifnot(is.logical(only_sep_sections)) + .check_char_vector_for_section_div(char_v, max_tree_depth, nrow(obj)) + + # Automatic establishment of intent + if (length(char_v) < nrow(obj)) { + only_sep_sections <- TRUE + } + + # Case where only separators or splits need to change externally + if (only_sep_sections && length(char_v) < nrow(obj)) { + if (length(char_v) == 1) { + char_v <- rep(char_v, max_tree_depth - 1) # -1 is the data row + } + # Case where char_v is longer than the max depth + char_v <- char_v[seq_len(min(max_tree_depth, length(char_v)))] + # Filling up with NAs the rest of the tree depth section div chr vector + missing_char_v_len <- max_tree_depth - length(char_v) + char_v <- c(char_v, rep(NA_character_, missing_char_v_len)) + # char_v <- unlist( + # lapply(tree_depths, function(tree_depth_i) char_v[seq_len(tree_depth_i)]), + # use.names = FALSE + # ) + } + + # Retrieving if it is a contentRow (no need for labelrow to be visible in this case) + content_row_tbl <- content_table(obj) + is_content_table <- isS4(content_row_tbl) && nrow(content_row_tbl) > 0 + + # Main table structure change + if (labelrow_visible(obj) || is_content_table) { + if (only_sep_sections) { + # Only tables are modified + trailing_section_div(tt_labelrow(obj)) <- NA_character_ + trailing_section_div(obj) <- char_v[1] + section_div(tree_children(obj), only_sep_sections = only_sep_sections) <- char_v[-1] + } else { + # All leaves are modified + trailing_section_div(tt_labelrow(obj)) <- char_v[1] + trailing_section_div(obj) <- NA_character_ + section_div(tree_children(obj), only_sep_sections = only_sep_sections) <- char_v[-1] + } + } else { + section_div(tree_children(obj), only_sep_sections = only_sep_sections) <- char_v + } + obj +})
only_sep_sections is a parameter that is used to change +only the separators (between splits) and not the data rows. It is +happening forcefully if set to TRUE, but it is +automatically activated when section_div(tbl) <- char_v +is a character vector of length < nrow(tbl). Notice that +the exception for ContentRow is activated by the switcher +is_content_table. This is because content rows do not have +visible label row. You see that in the main table structure change we +have two blocks depending on only_sep_sections. If +TRUE only the VTableTree are modified leading +to only split section separators to be modified. Also consider looking +at section_div getter and tests in +test-accessors.R to have more insights on the structure. +Also to understand exactly how this is bound to output, please check the +result of make_row_df() for the column +trailing_sep. Indeed, an alternative and iterative method +is used by make_row_df to retrieve the information about +the separators for each table row. Being it a trailing separator by +definition, we added header_section_div as a function and a +parameter of basic_table, so to possibly add an empty line +after the header (e.g. header_section_div(tbl) = " "). This +is not a trailing separator, but it is a separator that is added after +the header. To close the circle, please check how +trailing_sep and header_section_div is +propagated and printed/used in formatters::toString.
only_sep_sections
TRUE
section_div(tbl) <- char_v
< nrow(tbl)
is_content_table
test-accessors.R
make_row_df()
trailing_sep
make_row_df
header_section_div
basic_table
header_section_div(tbl) = " "
formatters::toString
vignettes/dev-guide/dg_split_machinery.Rmd
dg_split_machinery.Rmd
vignettes/dev-guide/dg_tabulation.Rmd
dg_tabulation.Rmd
vignettes/example_analysis_coxreg.Rmd
example_analysis_coxreg.Rmd
vignettes/exploratory_analysis.Rmd
exploratory_analysis.Rmd
vignettes/format_precedence.Rmd
format_precedence.Rmd
vignettes/introduction.Rmd
introduction.Rmd
vignettes/manual_table_construction.Rmd
manual_table_construction.Rmd
vignettes/sorting_pruning.Rmd
sorting_pruning.Rmd
Therefore, a fundamental difference between pruning and sorting is that sorting occurs at particular places in the table, as defined by a @@ -919,7 +908,7 @@
We see that a similar function to cont_n_allcols() is wrapped by one that allows a parameter j to be used to diff --git a/main/articles/split_functions.html b/main/articles/split_functions.html index d31eca490..2bfeff79d 100644 --- a/main/articles/split_functions.html +++ b/main/articles/split_functions.html @@ -34,7 +34,7 @@ rtables - 0.6.5.9012 + 0.6.5.9013
cont_n_allcols()
j
vignettes/split_functions.Rmd
split_functions.Rmd
vignettes/subsetting_tables.Rmd
subsetting_tables.Rmd
vignettes/tabulation_dplyr.Rmd
tabulation_dplyr.Rmd
vignettes/title_footer.Rmd
title_footer.Rmd
Becker G, Waddell A (2023). rtables: Reporting Tables. -R package version 0.6.5.9012, +R package version 0.6.5.9013, https://insightsengineering.github.io/rtables/, https://github.com/insightsengineering/rtables.
@Manual{, title = {rtables: Reporting Tables}, author = {Gabriel Becker and Adrian Waddell}, year = {2023}, - note = {R package version 0.6.5.9012, + note = {R package version 0.6.5.9013, https://insightsengineering.github.io/rtables/}, url = {https://github.com/insightsengineering/rtables}, }
ref_group
bold
as_html
header_sep_line
section_div<-
styler
col_fnotes_here
col_footnotes
section_div()
logical(1). Should column counts be displayed in the resulting table when this layout is applied to data
tail()
`section_div<-`()
header_section_div()
`header_section_div<-`()
R/tree_accessors.R
section_div.Rd
section_div can be used to set or get the section divider for a table object +produced by build_table(). When assigned in post-processing (section_div<-) +the table can have a section divider after every row, each assigned independently. +If assigning during layout creation, only split_rows_by() (and its related row-wise +splits) and analyze() have a section_div parameter that will produce separators +between split sections and data subgroups, respectively.
build_table()
split_rows_by()
analyze()
section_div(obj) + +# S4 method for VTableTree +section_div(obj) + +# S4 method for list +section_div(obj) + +# S4 method for TableRow +section_div(obj) + +section_div(obj, only_sep_sections = FALSE) <- value + +# S4 method for VTableTree +section_div(obj, only_sep_sections = FALSE) <- value + +# S4 method for list +section_div(obj, only_sep_sections = FALSE) <- value + +# S4 method for TableRow +section_div(obj, only_sep_sections = FALSE) <- value + +# S4 method for LabelRow +section_div(obj, only_sep_sections = FALSE) <- value + +header_section_div(obj) + +# S4 method for PreDataTableLayouts +header_section_div(obj) + +# S4 method for VTableTree +header_section_div(obj) + +header_section_div(obj) <- value + +# S4 method for PreDataTableLayouts +header_section_div(obj) <- value + +# S4 method for VTableTree +header_section_div(obj) <- value
Table object. This can be of any class that inherits from VTableTree +or TableRow/LabelRow.
logical(1). Defaults to FALSE for section_div<-. Allows +you to set the section divider only for sections that are splits or analyses if the number of +values is less than the number of rows in the table. If TRUE, the section divider will +be set for all rows of the table.
FALSE
character. Vector of single characters to use as section dividers. Each character +is repeated such that all section dividers span the width of the table. Each character that is +not NA_character_ will produce a trailing separator for each row of the table. value length +should reflect the number of rows, or be between 1 and the number of splits/levels. +See the Details section below for more information.
value
The section divider string. Each line that does not have a trailing separator +will have NA_character_ as section divider.
Assigned value to section divider must be a character vector. If any value is NA_character_ +the section divider will be absent for that row or section. When you want to only affect sections +or splits, please use only_sep_sections or provide a shorter vector than the number of rows. +Ideally, the length of the vector should be less than the number of splits with, eventually, the +leaf-level, i.e. DataRow where analyze results are. Note that if only one value is inserted, +only the first split will be affected. +If only_sep_sections = TRUE, which is the default for section_div() produced from the table +construction, the section divider will be set for all the splits and eventually analyses, but +not for the header or each row of the table. This can be set with header_section_div in +basic_table() or, eventually, with hsep in build_table(). If FALSE, the section +divider will be set for all the rows of the table.
only_sep_sections = TRUE
basic_table()
hsep
basic_table() parameter header_section_div for a global section divider.
# Data +df <- data.frame( + cat = c( + "really long thing its so ", "long" + ), + value = c(6, 3, 10, 1) +) +fast_afun <- function(x) list("m" = rcell(mean(x), format = "xx."), "m/2" = max(x) / 2) + +tbl <- basic_table() %>% + split_rows_by("cat", section_div = "~") %>% + analyze("value", afun = fast_afun, section_div = " ") %>% + build_table(df) + +# Getter +section_div(tbl) +#> [1] NA " " "~" NA " " "~" + +# Setter +section_div(tbl) <- letters[seq_len(nrow(tbl))] +tbl +#> all obs +#> ——————————————————————————————————— +#> really long thing its so +#> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +#> m 8 +#> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +#> m/2 5 +#> ccccccccccccccccccccccccccccccccccc +#> long +#> ddddddddddddddddddddddddddddddddddd +#> m 2 +#> eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +#> m/2 1.5 + +# last letter can appear if there is another table +rbind(tbl, tbl) +#> all obs +#> ——————————————————————————————————— +#> really long thing its so +#> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +#> m 8 +#> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +#> m/2 5 +#> ccccccccccccccccccccccccccccccccccc +#> long +#> ddddddddddddddddddddddddddddddddddd +#> m 2 +#> eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +#> m/2 1.5 +#> fffffffffffffffffffffffffffffffffff +#> really long thing its so +#> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +#> m 8 +#> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +#> m/2 5 +#> ccccccccccccccccccccccccccccccccccc +#> long +#> ddddddddddddddddddddddddddddddddddd +#> m 2 +#> eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +#> m/2 1.5 + +# header_section_div +header_section_div(tbl) <- "+" +tbl +#> all obs +#> ——————————————————————————————————— +#> +++++++++++++++++++++++++++++++++++ +#> really long thing its so +#> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +#> m 8 +#> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +#> m/2 5 +#> ccccccccccccccccccccccccccccccccccc +#> long +#> ddddddddddddddddddddddddddddddddddd +#> m 2 +#> eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee +#> m/2 1.5 + +
character(1). Set of character(s) to be repeated as the separator between the header and body of the table when rendered as text. Defaults to @@ -233,7 +231,7 @@
Title says Whaaaat
Oh, ok.
A: Drug X
B: Placebo
C: Combination
row1 {1}
5
row2
1, 2 {2}
{1} - row 1 - row footnote
{2} - row 2 - cell footnote
ha HA! Footer!