Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: junco
Title: Create Common Tables and Listings Used in Clinical Trials
Version: 0.1.6.9000
Version: 0.1.6.9001
Date: 2026-05-22
Authors@R: c(
person("Gabriel", "Becker", , "gabembecker@gmail.com", role = c("cre", "aut"),
Expand Down
7 changes: 6 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# junco 0.1.6.9000
# junco 0.1.6.9001

### Fixed
- Fixed `get_ref_info()` to accept ref_path = NULL (#359).
Expand Down Expand Up @@ -38,6 +38,11 @@
- Update new exported calls from rtables.officer
- update documentation to `roxygen2` 8.0.0
- Add extra statistics to `a_eair100_j` and introduce scaling factor `num_p_year` (default = 100) (#361)
- Unified `get_ref_info()` which now also returns `trt_var`, `ctrl_grp`, and `cur_col_val` (#295)
- `h_get_trtvar_refpath()` is marked as superseded
- `a_summarize_aval_chg_diff_j()` now uses `get_ref_info()`



### Added
- Added `categorize_pval()` for assigning p-values to validated, user-defined categories.
Expand Down
7 changes: 4 additions & 3 deletions R/a_summarize_aval_chg_diff.R
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,12 @@ a_summarize_aval_chg_diff_j <- function(

.in_ref_col <- FALSE
.ref_group <- NULL
ctrl_grp <- NULL
if (comp_btw_group) {
trt_var_refspec <- utils::tail(ref_path, n = 2)[1]
ref <- get_ref_info(ref_path, .spl_context)
trt_var_refspec <- ref$trt_var
checkmate::assert_true(identical(trt_var, trt_var_refspec))
# ctrl_grp
ctrl_grp <- utils::tail(ref_path, n = 1)
ctrl_grp <- ref$ctrl_grp

### check that ctrl_grp is a level of the treatment variable, in case riskdiff is requested
if (!ctrl_grp %in% levels(df[[trt_var]])) {
Expand Down
2 changes: 1 addition & 1 deletion R/cur_col_split_path_utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ cur_col_split_path <- function(.spl_context) {
checkmate::assert_list(.spl_context[nrow(.spl_context), "cur_col_split"], min.len = 1L)
checkmate::assert_list(.spl_context[nrow(.spl_context), "cur_col_split_val"], min.len = 1L)
checkmate::assert_character(.spl_context[nrow(.spl_context), "cur_col_split"][[1]], names = "unnamed")
checkmate::assert_character(.spl_context[nrow(.spl_context), "cur_col_split_val"][[1]], names = "unnamed")
checkmate::assert_character(.spl_context[nrow(.spl_context), "cur_col_split_val"][[1]])
checkmate::assert_true(
length(.spl_context[nrow(.spl_context), "cur_col_split"][[1]]) ==
length(.spl_context[nrow(.spl_context), "cur_col_split_val"][[1]])
Expand Down
80 changes: 53 additions & 27 deletions R/get_ref_info.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
#' @title Obtain Reference Information for a Global Reference Group
#'
#' @description `r lifecycle::badge("stable")`
#' Obtain reference information for a global reference group.
#'
#' This helper function can be used in custom analysis functions, by passing
#' an extra argument `ref_path` which defines a global reference group by
#' the corresponding column split hierarchy levels.
#'
#' @param ref_path (`character`)\cr reference group specification as an `rtables`
#' `colpath`, see details.
#' @param .spl_context (`data.frame`)\cr see [rtables::spl_context].
#' @param .var (`character`)\cr the variable being analyzed,
#' see [rtables::additional_fun_params].
#' @param ref_path (`character`)
#' Reference group specification as an `rtables` `colpath`; see Details.
#' @param .spl_context (`data.frame`)
#' Ancestor split-state information passed by `rtables`.
#' @param .var (`character`)
#' The variable being analyzed; see [rtables::additional_fun_params].
#'
#' @return A list with `ref_group` and `in_ref_col`, which can be used as
#' `.ref_group` and `.in_ref_col` as if being directly passed to an analysis
#' function by `rtables`, see [rtables::additional_fun_params].
#' @return
#' * `get_ref_info()` returns a list with:
#' * `ref_group`: the reference group data (a `data.frame` or vector depending
#' on `.var`), equivalent to `.ref_group` from [rtables::additional_fun_params].
#' * `in_ref_col`: logical, whether the current column is the reference column,
#' equivalent to `.in_ref_col` from [rtables::additional_fun_params].
#' * `trt_var`: the treatment variable name (last variable in `ref_path`).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically this is the most recent split's name, which is usually a variable name from the data, but its not guaranteed to be

#' * `ctrl_grp`: the reference group level (last level in `ref_path`).
#' * `cur_col_val`: the current column's value for `trt_var`.
#'
#' @details
#' The reference group is specified in `colpath` hierarchical fashion in
Expand Down Expand Up @@ -73,34 +78,55 @@
#' build_table(lyt, dm)
get_ref_info <- function(ref_path, .spl_context, .var = NULL) {
if (is.null(ref_path)) {
return(list(ref_group = NULL, in_ref_col = NULL))
return(
list(ref_group = NULL, in_ref_col = NULL, trt_var = NULL, ctrl_grp = NULL, cur_col_val = NULL)
)
}

checkmate::assert_character(ref_path, min.len = 2L, names = "unnamed")
checkmate::assert_true(length(ref_path) %% 2 == 0)
checkmate::assert_true(length(ref_path) %% 2L == 0L)
checkmate::assert_data_frame(.spl_context)

leaf_sc <- .spl_context[nrow(.spl_context), ]
vars_indices <- seq(from = 1L, to = length(ref_path) - 1L, by = 2L)
level_indices <- seq(from = 2L, to = length(ref_path), by = 2L)
ref_path_levels <- paste(ref_path[level_indices], collapse = ".")
cur_col_path <- cur_col_split_path(.spl_context)
cur_col_vars <- cur_col_path[seq(1L, length(cur_col_path), by = 2L)]
ref_path_last <- utils::tail(ref_path, 2L)
last_var_pos <- match(ref_path_last[1L], cur_col_vars)
cur_col_last_val <- if (!is.na(last_var_pos)) {
cur_col_path[2L * last_var_pos]
} else {
NULL
}

# If ref_path variables are outside of the current column split variable.
is_ref_in_colvars <- identical(leaf_sc$cur_col_split[[1]], ref_path[vars_indices])
if (!is_ref_in_colvars) {
return(list(ref_group = NULL, in_ref_col = NULL))
ref_path_val_pos <- seq(2L, length(ref_path), by = 2L)
ref_path_any_vals <- ref_path
ref_path_any_vals[ref_path_val_pos] <- "*"
if (!in_column(ref_path_any_vals, .spl_context)) {
return(
list(
ref_group = NULL,
in_ref_col = NULL,
trt_var = ref_path_last[1L],
ctrl_grp = ref_path_last[2L],
Comment on lines +109 to +110

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the name trt_var / ctrl_grp ? It does not need to be treatment var or control group, I think.

cur_col_val = cur_col_last_val
)
)
}

# Prepare in_ref_col.
in_ref_col <- identical(leaf_sc$cur_col_split_val[[1]], ref_path[level_indices])

# Prepare ref_group.
full_df <- leaf_sc$full_parent_df[[1]]
row_in_ref_group <- leaf_sc[[ref_path_levels]][[1]]
leaf_sc <- .spl_context[nrow(.spl_context), ]
full_df <- leaf_sc$full_parent_df[[1L]]
ref_path_levels <- paste(ref_path[ref_path_val_pos], collapse = ".")
row_in_ref_group <- leaf_sc[[ref_path_levels]][[1L]]
ref_group <- full_df[row_in_ref_group, ]
if (!is.null(.var)) {
ref_group <- ref_group[[.var]]
}

list(ref_group = ref_group, in_ref_col = in_ref_col)
list(
ref_group = ref_group,
in_ref_col = in_column(ref_path, .spl_context),
trt_var = ref_path_last[1L],
ctrl_grp = ref_path_last[2L],
cur_col_val = cur_col_last_val
)
}
4 changes: 4 additions & 0 deletions R/h_freq_funs.R
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,11 @@ h_df_add_newlevels <- function(df, .var, new_levels, addstr2levs = NULL, new_lev

#' Get Treatment Variable Reference Path
#'
#' @description `r lifecycle::badge("superseded")`
#'
#' Retrieves the treatment variable reference path from the provided context.
#' Prefer [get_ref_info()] which now returns `trt_var`, `ctrl_grp`, and
#' `cur_col_val` in addition to `ref_group` and `in_ref_col`.
#'
#' @param ref_path (`character`)\cr Reference path for treatment variable.
#' @param .spl_context (`data.frame`)\cr Current split context.
Expand Down
30 changes: 19 additions & 11 deletions man/get_ref_info.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions man/h_get_trtvar_refpath.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tests/testthat/test-cur_col_split_path.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ test_that("cur_col_split_path() works for a single-level split", {
expect_identical(res, exp)
})

test_that("cur_col_split_path() accepts named split values", {
spl_context <- data.frame(
cur_col_split = I(list("ARM")),
cur_col_split_val = I(list(c(ARM = "Placebo")))
)

res <- cur_col_split_path(spl_context)
exp <- c("ARM", "Placebo")

expect_identical(unname(res), exp)
})

test_that("cur_col_split_path() uses the leaf row split for a single-level split", {
spl_context <- data.frame(
cur_col_split = I(list("ARM_0", "ARM")),
Expand Down
Loading
Loading