Nothing
context("Accessor tests")
test_that("various accessors work at the layout/table level", {
## coltree
col_extra_args <- rtables:::col_extra_args
l <- basic_table() %>%
split_cols_by("ARM") %>%
split_cols_by_multivar(c("AGE", "BMRKR1")) %>%
analyze_colvars(list(mean, sd))
pred <- coltree(l, DM)
tbl <- build_table(l, DM)
postd <- coltree(tbl)
expect_identical(pred, postd)
expect_identical(
col_extra_args(pred),
col_extra_args(postd)
)
expect_identical(
col_exprs(l, DM),
col_exprs(col_info(tbl))
)
expect_identical(
clayout(tbl),
postd
)
expect_identical(
colcount_format(tbl),
"(N=xx)"
)
## even when not displayed
colcount_format(tbl) <- "xx"
expect_identical(
colcount_format(tbl),
"xx"
)
ccounts <- col_counts(tbl)
expect_identical(
col_counts(tbl, path = c("ARM", "B: Placebo", "multivars", "AGE")),
ccounts[3]
)
newccs <- rep(7L, ncol(tbl))
col_counts(tbl) <- newccs
expect_identical(
newccs,
col_counts(tbl)
)
col_counts(tbl, path = c("ARM", "B: Placebo", "multivars", "BMRKR1")) <- 5L
expect_identical(
rep(c(7L, 5L, 7L), times = c(3, 1, 2)),
col_counts(tbl)
)
col_total(tbl) <- 75L
expect_identical(
col_total(tbl),
75L
)
disp_ccounts <- rtables:::disp_ccounts
`disp_ccounts<-` <- rtables:::`disp_ccounts<-`
olddisp <- disp_ccounts(tbl)
disp_ccounts(tbl) <- !olddisp
expect_identical(
!olddisp,
disp_ccounts(tbl)
)
l2 <- l
top_left(l2) <- "Hiya!!!"
expect_identical(top_left(l2), "Hiya!!!")
tbl2 <- build_table(l2, DM)
expect_identical(top_left(tbl2), "Hiya!!!")
expect_identical(page_titles(tbl), character())
page_titles(tbl) <- "Woah a page title!"
expect_identical(
page_titles(tbl),
"Woah a page title!"
)
tt_level <- rtables:::tt_level
`tt_level<-` <- rtables:::`tt_level<-`
expect_identical(tt_level(tbl), 1L)
tt_level(tbl) <- 2
expect_error(
table_inset(tbl) <- -1,
"invalid table_inset value"
)
})
test_that("Accessors for Split objects work", {
myspl <- VarLevelSplit("AGE", "My age yo",
labels_var = "AGE2",
cfun = list(identity),
cformat = "xx.x",
split_fun = identity,
split_format = "xx.xx",
split_name = "names_bro",
indent_mod = 1,
cindent_mod = 2,
extra_args = list("hiya"),
child_labels = "default"
)
expect_identical(obj_label(myspl), "My age yo")
obj_label(myspl) <- "new label"
expect_identical(obj_label(myspl), "new label")
expect_identical(obj_format(myspl), "xx.xx")
obj_format(myspl) <- "xx.x"
expect_identical(obj_format(myspl), "xx.x")
split_exargs <- rtables:::split_exargs
`split_exargs<-` <- rtables:::`split_exargs<-`
expect_identical(split_exargs(myspl), list("hiya"))
split_exargs(myspl) <- list("whaaaaaaaaaaaaat is this")
expect_identical(split_exargs(myspl), list("whaaaaaaaaaaaaat is this"))
label_kids <- rtables:::label_kids
`label_kids<-` <- rtables:::`label_kids<-`
expect_true(is.na(label_kids(myspl)))
label_kids(myspl) <- "hidden"
expect_identical(label_kids(myspl), FALSE)
label_kids(myspl) <- NA
expect_true(is.na(label_kids(myspl)))
varlbs <- c("age", "biomarker1")
mvarspl <- MultiVarSplit(c("AGE", "BMRKR1"),
"My Multivar",
varlabels = varlbs
)
spl_varnames <- rtables:::spl_varnames
`spl_varnames<-` <- rtables:::`spl_varnames<-`
expect_identical(
spl_varnames(mvarspl),
c("AGE", "BMRKR1")
)
spl_varnames(mvarspl) <- c("stuff1", "stuff2")
expect_identical(
spl_varnames(mvarspl),
paste0("stuff", 1:2)
)
spl_varlabels <- rtables:::spl_varlabels
`spl_varlabels<-` <- rtables:::`spl_varlabels<-`
expect_identical(
spl_varlabels(mvarspl),
varlbs
)
spl_varlabels(mvarspl) <- LETTERS[1:2]
expect_identical(
spl_varlabels(mvarspl),
LETTERS[1:2]
)
mvarspl2 <- MultiVarSplit(c("A", "B"))
expect_identical(
spl_varnames(mvarspl2),
spl_varlabels(mvarspl2)
)
spl_varnames(mvarspl2) <- c("C", "D")
expect_identical(
spl_varnames(mvarspl2),
spl_varlabels(mvarspl2)
)
})
test_that("header sep setting works", {
dflt <- default_hsep()
hsep_test <- function(tab, exp) {
expect_identical(horizontal_sep(tab), exp)
expect_identical(horizontal_sep(tab[1:5, ]), exp)
expect_identical(horizontal_sep(tab[, 1:3]), exp)
expect_identical(horizontal_sep(tab[1:5, 1:3]), exp)
expect_identical(horizontal_sep(tree_children(tab)[[1]]), exp)
TRUE
}
lyt <- make_big_lyt()
tbl <- build_table(lyt, rawdat)
hsep_test(tbl, dflt)
tbl2 <- tbl
horizontal_sep(tbl2) <- "="
hsep_test(tbl2, "=")
})
# section_div tests ------------------------------------------------------------
test_structure_with_a_getter <- function(tbl, getter, val_per_lev) {
# Main table obj
expect_identical(tbl %>% getter(), val_per_lev$global)
# Its labelrow (could be also not visible)
expect_identical(tt_labelrow(tbl) %>% getter(), val_per_lev$global_labelrow)
# First split row + its labels
split1 <- tree_children(tbl)[[1]]
expect_identical(split1 %>% getter(), val_per_lev$split)
expect_identical(tt_labelrow(split1) %>% getter(), val_per_lev$split_labelrow)
# Content table checks if there
content_elem_tbl <- content_table(split1)
if (nrow(content_elem_tbl) > 0) {
expect_identical(content_elem_tbl %>% getter(), val_per_lev$content)
expect_identical(tt_labelrow(content_elem_tbl) %>% getter(), val_per_lev$content_labelrow)
expect_identical(tree_children(content_elem_tbl)[[1]] %>% getter(), val_per_lev$contentrow)
}
## The elementary table has it?
leaves_elementary_tbl <- tree_children(split1)[[1]]
expect_identical(leaves_elementary_tbl %>% getter(), val_per_lev$elem_tbl)
expect_identical(tt_labelrow(leaves_elementary_tbl) %>% getter(), val_per_lev$elem_tbl_labelrow)
# Data rows has it?
for (i in seq_len(nrow(leaves_elementary_tbl))) {
expect_identical(tree_children(leaves_elementary_tbl)[[i]] %>% getter(), val_per_lev$datarow[i])
}
}
sdf_row_ok <- function(i, rdf) {
trail_sep <- rdf$trailing_sep[i]
pth <- rdf$path[[i]]
sect_div_pth <- rdf$sect_div_from_path[[i]]
self_div <- rdf$self_section_div[i]
paths_match <- paste(pth, collapse = "") == paste(sect_div_pth, collapse = "")
if (rdf$node_class[i] == "LabelRow") {
## label rows have NA for section_div_from_path even
## though they technically have a path value because
## its wrong and doesn't actually path to that row
## can't path to a label row
ret <- is.na(sect_div_pth) &&
(is.na(trail_sep) || trail_sep == self_div)
} else if (is.na(trail_sep)) {
ret <- is.na(self_div) &&
(all(is.na(sect_div_pth)) || identical(pth, sect_div_pth))
} else if (is.na(self_div)) {
## trail_sep is NOT na here, so it has to inherit from somewhere else
ret <- !paths_match
} else {
## assumes we set different seps on table and last row in table
## ok for our unit tests but not safe hard assumption "in the wild"
divmatch <- trail_sep == self_div ## both non na
## seps match if and only if paths match
ret <- paths_match == divmatch
}
ret
}
sect_div_info_ok <- function(tt, sdf = section_div_info(tt)) {
expect_true(all(vapply(seq_len(nrow(sdf)), sdf_row_ok, rdf = sdf, TRUE)))
}
test_that("section_div getter and setter works", {
df <- data.frame(
cat = c(
"re", "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)
sdf <- section_div_info(tbl)
sect_div_info_ok(sdf = sdf)
## basic section_div_at_path checks
## this should have NO section_divs set on individual rows...
## label row "pathing" is stupid and I hate it
res <- expect_silent(vapply(sdf$path, function(pth) section_div_at_path(tbl, pth, labelrow = TRUE), ""))
expect_true(all(is.na(res)))
expect_equal(
section_div_at_path(tbl, c("cat", "re")),
"~"
)
expect_equal(
section_div_at_path(tbl, c("cat", "re", "value")),
" "
)
expect_error(section_div_at_path(tbl, c("*", "*", "*", "*", "*")),
"Paths including '*' wildcards are not currently supported",
fixed = TRUE
)
expect_error(
section_div_at_path(tbl, c("cat", "lol")),
"Path appears invalid"
)
tbl_content <- basic_table() %>%
split_rows_by("cat", section_div = "~") %>%
summarize_row_groups() %>% # This makes them not visible
analyze("value", afun = fast_afun, section_div = " ") %>%
build_table(df)
sect_div_info_ok(tbl_content)
val_per_lev <- list(
"global" = NA_character_,
"global_labelrow" = NA_character_,
"split" = "~",
"split_labelrow" = NA_character_,
"content" = NA_character_, # If there is a summarize_row_groups this is present
"contentrow" = NA_character_,
"content_labelrow" = NA_character_,
"elem_tbl_labelrow" = NA_character_,
"elem_tbl" = " ",
"datarow" = c(NA_character_, NA_character_)
)
# Checks of structure - precedence is top to bottom
test_structure_with_a_getter(tbl,
getter = trailing_section_div,
val_per_lev = val_per_lev
)
test_structure_with_a_getter(tbl_content,
getter = trailing_section_div,
val_per_lev = val_per_lev
)
# Checks that section div and printing works together
expect_identical(section_div(tbl), make_row_df(tbl)$trailing_sep)
expect_identical(section_div(tbl_content), make_row_df(tbl_content)$trailing_sep)
# MAIN assignment setter - this is clean, i.e. is only node base and not real section div
## this behavior is changed, but I think the new behavior
## is correct. we now have section_div_at_path (which
## supports * wildcards) to set actual section divs
## and section_div_info to easily determine the path
## an effective div is coming from
section_div(tbl) <- letters[seq_len(nrow(tbl))]
section_div(tbl_content) <- letters[seq_len(nrow(tbl))]
sect_div_info_ok(tbl)
val_per_lev <- list(
"global" = NA_character_,
"global_labelrow" = NA_character_,
"split" = NA_character_,
"split_labelrow" = "a",
"content" = NA_character_,
"contentrow" = NA_character_,
"content_labelrow" = NA_character_,
"elem_tbl_labelrow" = NA_character_,
"elem_tbl" = NA_character_, # "c",
"datarow" = c("b", "c")
)
val_per_lev_cont <- list(
"global" = NA_character_,
"global_labelrow" = NA_character_,
"split" = NA_character_,
"split_labelrow" = NA_character_, # "a",
"content" = NA_character_,
"contentrow" = "a", # NA_character_,
"content_labelrow" = NA_character_,
"elem_tbl_labelrow" = NA_character_,
"elem_tbl" = NA_character_, # "c",
"datarow" = c("b", "c")
)
# Checks of structure - precedence is top to bottom
test_structure_with_a_getter(tbl,
getter = trailing_section_div,
val_per_lev = val_per_lev
)
test_structure_with_a_getter(tbl_content,
getter = trailing_section_div,
val_per_lev = val_per_lev_cont
)
# Checks that section div and printing works together
expect_identical(section_div(tbl), make_row_df(tbl)$trailing_sep)
expect_identical(section_div(tbl_content), make_row_df(tbl_content)$trailing_sep)
separators <- strsplit(toString(tbl, widths = c(4, 10)), "\n")[[1]][c(4, 6, 9, 11, 13)]
separators2 <- strsplit(toString(tbl_content, widths = c(4, 10)), "\n")[[1]][c(4, 6, 9, 11, 13)]
expect_identical(separators, separators2)
tbla <- tbl
expect_warning({
section_div(tbla) <- letters
})
expect_identical(tbl, tbla)
# -1 is the table end
expect_true(check_all_patterns(separators, letters[seq_len(nrow(tbl) - 1)], len = 17))
## https://github.com/insightsengineering/rtables/issues/1023
## section_div<-, section_div_at_path<-
## 'big', ie non-trivially structured, table
big_tbl <- build_table(make_big_lyt(), rawdat)
tbl3 <- tbl2 <- big_tbl
sect_div_info_ok(tbl2)
ltrs <- rep(letters, length.out = NROW(tbl2))
section_div(tbl2) <- ltrs
sect_div_info_ok(tbl2)
txtvec <- strsplit(toString(tbl2), split = "\n")[[1]]
sepinds <- seq(from = 6, to = length(txtvec) - 1, by = 2)
wid <- nchar(txtvec[6])
expect_true(check_all_patterns(txtvec[sepinds], head(ltrs, -1), len = wid))
## when full length vector is given, divs are set on individual rows
rdf2 <- make_row_df(tbl2)
expect_identical(rdf2$trailing_sep, rdf2$self_section_div)
## set subtable section div and have it override existing row div
## also support for wildcard in section_div_at_path<-, including
## ending on a wildcard
tbl4 <- tbl2
section_div_at_path(tbl4, c("RACE", "*", "FACTOR2", "*", "*")) <- "-"
sdf4 <- section_div_info(tbl4)
sect_div_info_ok(sdf = sdf4)
txtvec4 <- strsplit(toString(tbl4), split = "\n")[[1]]
## bad paths of all the various types give informative errors
expect_error(
{
section_div_at_path(tbl4, c("RACE", "*", "FACTOR2", "*", "*", "@content")) <- "-"
},
"Unable to resolve * in path",
fixed = TRUE
)
expect_error(
{
section_div_at_path(tbl4, c("RACE", "feline", "FACTOR2", "*", "*")) <- "-"
},
"Unable to find child(ren) 'feline'",
fixed = TRUE
)
expect_error(
{
section_div_at_path(tbl4, c("RACE", "*", "FACTOR2", "*", "*", "*"), labelrow = TRUE) <- "-"
},
"Unable to resolve * in path",
fixed = TRUE
)
expect_error(
{
section_div_at_path(tbl4, c("RACE", "BLACK", "FACTOR2", "A", "AGE", "mean", "*")) <- "-"
},
"Path continues after resolving to individual row"
)
expect_equal(sum(sdf4$trailing_sep == "-"), 8)
ltrinds4 <- c(5, 7, 11, 13, 18, 20, 24, 26)
modltrs <- ltrs
modltrs[ltrinds4] <- "-"
expect_true(check_all_patterns(txtvec4[sepinds], head(modltrs, -1), wid))
expect_false(identical(sdf4$trailing_sep, sdf4$self_section_div))
## crazy people with their crazy ... label and content rows
## both visible
lytcrazy <- basic_table() |>
split_rows_by("ARM", child_labels = "visible") |>
summarize_row_groups() |>
analyze("AGE")
## regression for unreported bug
tblcrazy <- build_table(lytcrazy, DM)
section_div(tblcrazy) <- letters[seq_len(nrow(tblcrazy))]
txtcrazy <- strsplit(toString(tblcrazy), split = "\n")[[1]]
expect_true(
check_all_patterns(
txtcrazy[seq(4, length(txtcrazy), by = 2)],
letters[1:(nrow(tblcrazy) - 1)],
len = nchar(txtcrazy[2])
)
)
expect_error({
section_div_at_path(tbl, c("*", "*", "*", "*", "*", "*")) <- " "
})
## stupid for coverage
rws <- collect_leaves(tbl, add.labrows = TRUE)
rws2 <- expect_silent(lapply(rws, function(r) {
section_div(r) <- "W"
r
}))
expect_equal(
vapply(rws2, section_div, "", USE.NAMES = FALSE),
rep("W", length(rws))
)
})
test_that("the split only setter works", {
fast_afun <- function(x) list("m" = rcell(mean(x), format = "xx."), "m/2" = max(x) / 2)
tbla <- tbl <- basic_table() %>%
split_rows_by("ARM", section_div = "=") %>%
split_rows_by("STRATA1", section_div = "-") %>%
analyze("BMRKR1") %>%
build_table(DM)
sect_div_info_ok(tbl)
replace_sec_div <- section_div(tbl)
replace_sec_div[replace_sec_div == "="] <- "a"
replace_sec_div[replace_sec_div == "-"] <- "b"
section_div(tbl) <- c("a", "b")
sdf <- section_div_info(tbl)
expect_identical(section_div(tbl), replace_sec_div)
expect_identical(sdf$trailing_sep, replace_sec_div)
## when only_sep_sections is true, divs are set on the subtable not
## the row
expect_true(all(is.na(sdf$self_section_div)))
sect_div_info_ok(sdf = sdf)
expect_warning(
{
section_div(tbla, only_sep_sections = TRUE) <- letters
},
"Unable to find 4 levels of nesting in table structure."
)
## the above is setting "c" on the analysis tables, but that doesn't
## matter since they are perfectly masked by the b's from the
## STRATA1 split facets. That's "probably wrong behavior" (setting
## the invisible 'c' section divs) technically, but it doesn't
## make any difference in practice and I'm not convinced we can make
## the nesting-detection heuristic smart enough to handle that
## successfully.
##
## Their text renderings are identical, though...
expect_false(identical(tbl, tbla))
expect_identical(toString(tbl), toString(tbla))
# multiple analyze
tbl <- basic_table(header_section_div = " ") %>%
split_cols_by("ARM") %>%
split_rows_by("SEX", split_fun = drop_split_levels) %>%
analyze("AGE") %>%
split_rows_by("RACE", split_fun = drop_split_levels) %>%
split_rows_by("SEX", split_fun = drop_split_levels) %>%
analyze("AGE") %>%
build_table(DM)
tbl2 <- tbl
sect_div_info_ok(tbl)
section_div(tbl) <- c("-", NA_character_)
sect_div_info_ok(tbl)
section_div(tbl2) <- c("-")
sect_div_info_ok(tbl2)
expect_identical(
section_div(tbl)[seq_len(6)],
c(NA_character_, "-", NA_character_, "-", NA_character_, NA_character_)
)
expect_identical(
section_div(tbl),
section_div(tbl2)
)
})
test_that("header_section_div works", {
lyt <- basic_table(header_section_div = "+") %>%
split_rows_by("STRATA1") %>%
analyze("BMRKR1")
expect_identical(header_section_div(lyt), "+")
header_section_div(lyt) <- "<"
expect_identical(header_section_div(lyt), "<")
tbl <- lyt %>% build_table(DM)
expect_identical(header_section_div(tbl), "<")
header_section_div(tbl) <- "+"
expect_identical(header_section_div(tbl), "+")
header_sdiv <- strsplit(toString(tbl), "\n")[[1]][3]
expect_true(check_pattern(header_sdiv, "+", nchar(header_sdiv)))
})
test_that("top_level_section_div works", {
lyt <- basic_table(top_level_section_div = "a") %>%
split_cols_by("ARM") %>%
split_rows_by("SEX", split_fun = drop_split_levels) %>%
analyze("AGE") %>%
split_rows_by("RACE", split_fun = drop_split_levels) %>%
split_rows_by("SEX", split_fun = drop_split_levels) %>%
analyze("AGE")
tbl <- build_table(lyt, DM)
expect_identical(top_level_section_div(lyt), "a")
top_level_section_div(lyt) <- "="
expect_identical(top_level_section_div(lyt), "=")
tbl <- build_table(lyt, DM)
top_lev_div_str <- strsplit(toString(tbl), "\n")[[1]][7]
expect_true(check_pattern(top_lev_div_str, "=", nchar(top_lev_div_str)))
})
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.