pharmaverse / pharmaverse/rtables

Feature request: passing .alt_df_full to afuns when using build_table(lyt, df)

Open
#1,089 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
R
Stars
260
Forks
53
PR merge metrics
No merged PRs in 30d

Description

Would it be possible to consider passing the input dataframe df to .alt_df_full when build_table has been called with no alt_counts_df dataframe?

The current behaviour requires to set a default for .alt_df_full in the afun as demonstrated in following reprex.

library(rtables)
#> Loading required package: formatters
#> 
#> Attaching package: 'formatters'
#> The following object is masked from 'package:base':
#> 
#>     %||%
#> Loading required package: magrittr
#> 
#> Attaching package: 'rtables'
#> The following object is masked from 'package:utils':
#> 
#>     str
adsl <- ex_adsl

myafun <- function(df, .var, .alt_df_full, .spl_context){
  xx <- .alt_df_full
  yy <- .spl_context$full_parent_df[[1]]
  in_rows(.list = list(full_parent_df = NROW(yy), 
                       .alt_df_full = NROW(xx),
                       df = NROW(df)),
          .labels = c("# (full_parent_df)",
                      "# (.alt_df_full)",
                      "# (df)"))
}

lyt <- basic_table() |> 
  split_cols_by("ARM") |> 
  analyze(vars = "STUDYID", afun = myafun)

build_table(lyt, adsl, alt_counts_df = adsl)
#>                      A: Drug X   B: Placebo   C: Combination
#> ————————————————————————————————————————————————————————————
#> # (full_parent_df)      400         400            400      
#> # (.alt_df_full)        400         400            400      
#> # (df)                  134         134            132
build_table(lyt, adsl)
#> Error: Error applying analysis function (var - STUDYID): argument ".alt_df_full" is missing, with no default
#>  occured at (row) path: root

# set default for .alt_df_full to NULL when not passed by rtables splitting machinery

myafun2 <- function(df, .var, .alt_df_full = NULL, .spl_context){
  xx <- .alt_df_full
  yy <- .spl_context$full_parent_df[[1]]
  in_rows(.list = list(full_parent_df = NROW(yy), 
                       .alt_df_full = NROW(xx),
                       df = NROW(df)),
          .labels = c("# (full_parent_df)",
                      "# (.alt_df_full)",
                      "# (df)"))
}

lyt2 <- basic_table() |> 
  split_cols_by("ARM") |> 
  analyze(vars = "STUDYID", afun = myafun2)

build_table(lyt2, adsl)
#>                      A: Drug X   B: Placebo   C: Combination
#> ————————————————————————————————————————————————————————————
#> # (full_parent_df)      400         400            400      
#> # (.alt_df_full)         0           0              0       
#> # (df)                  134         134            132
build_table(lyt2, adsl, alt_counts_df = adsl)
#>                      A: Drug X   B: Placebo   C: Combination
#> ————————————————————————————————————————————————————————————
#> # (full_parent_df)      400         400            400      
#> # (.alt_df_full)        400         400            400      
#> # (df)                  134         134            132

# set default for .alt_df_full to full_parent_df when not passed by rtables splitting machinery
# this would be the desired passing when no alt_counts_df has been supplied in build_table call

myafun3 <- function(df, .var, .alt_df_full = .spl_context$full_parent_df[[1]], .spl_context){
  xx <- .alt_df_full
  yy <- .spl_context$full_parent_df[[1]]
  in_rows(.list = list(full_parent_df = NROW(yy), 
                       .alt_df_full = NROW(xx),
                       df = NROW(df)),
          .labels = c("# (full_parent_df)",
                      "# (.alt_df_full)",
                      "# (df)"))
}

lyt3 <- basic_table() |> 
  split_cols_by("ARM") |> 
  analyze(vars = "STUDYID", afun = myafun3)

build_table(lyt3, adsl, alt_counts_df = adsl)
#>                      A: Drug X   B: Placebo   C: Combination
#> ————————————————————————————————————————————————————————————
#> # (full_parent_df)      400         400            400      
#> # (.alt_df_full)        400         400            400      
#> # (df)                  134         134            132
build_table(lyt3, adsl)
#>                      A: Drug X   B: Placebo   C: Combination
#> ————————————————————————————————————————————————————————————
#> # (full_parent_df)      400         400            400      
#> # (.alt_df_full)        400         400            400      
#> # (df)                  134         134            132

Created on 2026-05-12 with reprex v2.1.1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the build_table(lyt, df) entry point and trace the splitting machinery that supplies .alt_df_full, .spl_context$full_parent_df, and alt_counts_df. Compare the reprex calls with and without alt_counts_df. Done means an afun can receive the full input dataframe through .alt_df_full when no alternate counts dataframe is supplied, while the existing alt_counts_df behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
api, data
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.