Skip to content

[Feature Request]: Allow excluding rows from the g_forest(). #1498

Description

@wwojciech

Feature description

In the current implementation of g_forest(), the function attempts to plot all values (except of those in LabelRow) from the columns specified by the col_x and col_ci arguments. However, there are cases where some values are NULL and should not be included in the forest plot.

The following artificial example illustrates the issue (please ignore the meaning and logic of the numbers):

library(rtables)

DM2 <- subset(
  DM,
  COUNTRY %in% c("USA", "CAN", "CHN") & ARM %in% c("A: Drug X", "B: Placebo")
)
DM2$diff <- "diff"

cfun <- function(df, labelstr, .spl_context, split_vals) {
  leaf_splc <- .spl_context[nrow(.spl_context), ]
  if (leaf_splc$cur_col_split_val %in% split_vals) {
    rcell(nrow(df), label = leaf_splc$value)
  } else {
    rcell(NULL, label = leaf_splc$value)
  }
}

afun <- function(df, labelstr, .spl_context, split_vals) {
  leaf_splc <- .spl_context[nrow(.spl_context), ]
  if (leaf_splc$cur_col_split_val %in% split_vals) {
    rcell(0.5, label = "MyStat")
  } else {
    rcell(15, label = "MyStat")
  }
}

lyt <- basic_table() |>
  split_cols_by("ARM", split_fun = drop_split_levels) |>
  split_cols_by("diff", nested = FALSE) |>
  split_rows_by("COUNTRY", split_fun = drop_split_levels) |>
  summarize_row_groups(
    cfun = cfun,
    format = NULL,
    extra_args = list(split_vals = c("A: Drug X", "B: Placebo"))
  ) |>
  analyze(
    "BMRKR1",
    afun = afun,
    extra_args = list(split_vals = "diff")
  )

tbl <- build_table(lyt, DM2)

row_paths_summary(tbl)

In this example, we would like to plot col_x = 3. However,

g_forest(tbl, col_x = 3)
Error in `geom_point()`:
! Problem while setting up geom aesthetics.Error occurred in the 5th layer.
Caused by error in `check_aesthetics()`:
! Aesthetics must be either length 1 or the same as the data (6).Fix the following mappings: `x`.
Run `rlang::last_trace()` to see where the error occurred.

It fails because some rows in the 3rd column contain NULL values.

When we redefine cfun to return NA instead of NULL, g_forest(tbl, col_x = 3) no longer fails:

cfun <- function(df, labelstr, .spl_context, split_vals) {
  leaf_splc <- .spl_context[nrow(.spl_context), ]
  if (leaf_splc$cur_col_split_val %in% split_vals) {
    rcell(nrow(df), label = leaf_splc$value)
  } else {
    rcell(NA, label = leaf_splc$value)
  }
}

Possible solutions:

We see two possible approaches to address this issue.

1. Automatically exclude non-plottable values

Before plotting, g_forest() could automatically exclude rows where the value in col_x is NULL, or another non-numeric value (e.g., "", character(0)).

2. Introduce a new argument, e.g. exclude_rows

Add a new argument, exclude_rows = NULL, that allows users to explicitly specify the indices of rows to be omitted from the forest plot. The row indices could be defined relative to either row_paths_summary(tbl) or as_result_df(tbl). The latter would likely be simpler, since g_forest() already converts the input table using as_result_df(tbl).

The implementation could be as simple as:

tbl_df <- as_result_df(tbl)

if (!is.null(exclude_rows)) {
  tbl_df <- tbl_df[-exclude_rows, ]
}

This second approach is more general, as it gives users a straightforward way to exclude arbitrary rows from the forest plot while preserving the existing behavior for all other rows. It also avoids introducing implicit filtering rules based on the contents of col_x / col_ci, leaving the decision of which rows to plot entirely under the user's control.

Code of Conduct

  • I agree to follow this project's Code of Conduct.

Contribution Guidelines

  • I agree to follow this project's Contribution Guidelines.

Security Policy

  • I agree to follow this project's Security Policy.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions