Skip to content

Commit bf71443

Browse files
authored
Merge pull request #214 from atorus-research/devel
Tplyr 1.3.3: fix all-missing (NA) count target sort warning (#213)
2 parents cf9a489 + 4b6f306 commit bf71443

5 files changed

Lines changed: 78 additions & 11 deletions

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: Tplyr
22
Title: A Traceability Focused Grammar of Clinical Data Summary
3-
Version: 1.3.2
3+
Version: 1.3.3
44
Authors@R:
55
c(
66
person(given = "Eli",

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Tplyr 1.3.3
2+
3+
## Bug fixes
4+
- Resolve #213 Fix spurious `no non-missing arguments to max` warning and `-Inf` sort value when a count layer targets an all-missing (`NA`) variable
5+
16
# Tplyr 1.3.2
27

38
## Internal Changes

R/sort.R

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ get_data_order_count <- function(formatted_data, formatted_col_index,
530530
varn_df <- varn_df %>%
531531
bind_rows(tibble(
532532
!!target_var[[1]] := names(missing_count_list),
533-
!!varN_name := seq_along(missing_count_list) + max(varn_df[, 2])
533+
!!varN_name := seq_along(missing_count_list) +
534+
if (nrow(varn_df) == 0) 0 else max(varn_df[, 2])
534535
))
535536
} else {
536537
varn_df <- varn_df %>%
@@ -590,7 +591,8 @@ get_data_order_count <- function(formatted_data, formatted_col_index,
590591
fact_df <- fact_df %>%
591592
bind_rows(tibble(
592593
!!target_var[[1]] := names(missing_count_list),
593-
factor_index = seq_along(missing_count_list) + max(fact_df$factor_index)
594+
factor_index = seq_along(missing_count_list) +
595+
if (nrow(fact_df) == 0) 0 else max(fact_df$factor_index)
594596
)) %>%
595597
distinct(!!target_var[[1]], .keep_all = TRUE)
596598
} else {
@@ -719,8 +721,11 @@ get_data_order_byvarn <- function(formatted_data, by_varn_df, by_var, by_column_
719721
by_values <- unlist(formatted_data[, by_column_index])
720722

721723
# Look up the VARN value for each row. Unmatched rows get a default
722-
# value that places them at the end.
723-
default_sort <- max(unlist(by_varn_df[, 2])) + 1
724+
# value that places them at the end. When the target has no non-missing
725+
# levels (e.g. an all-NA target variable) by_varn_df is empty, so guard
726+
# against max() warning and returning -Inf on an empty set.
727+
varn_values <- unlist(by_varn_df[, 2])
728+
default_sort <- if (length(varn_values) == 0) 1 else max(varn_values) + 1
724729
varns <- map_dbl(by_values, function(a_by) {
725730

726731
# Row containing the index and the value

cran-comments.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
1-
## Submission 1.3.1
2-
* Internal refactoring and performance optimizations for nested count layers
3-
* Bug fixes for nested count sorting, negative number extraction, vignette options handling, difftime attributes, apply_row_masks, and risk difference with NAs
1+
## Submission 1.3.3
2+
3+
This is a patch release (current CRAN version 1.3.2). It fixes a single bug, with
4+
no user-facing API change:
5+
6+
* Resolve a spurious "no non-missing arguments to max" warning and an invalid
7+
`-Inf` sort value produced when a count layer targets an all-missing (`NA`)
8+
variable (#213).
49

510
## Test Environments
611

712
* Local macOS (aarch64-apple-darwin20), R 4.5.1
8-
* GitHub Actions: windows-latest (release), macOS-latest (release), ubuntu-latest (release, devel, oldrel-1)
13+
* GitHub Actions:
14+
* windows-latest (R release)
15+
* macOS-latest (R release)
16+
* ubuntu-latest and ubuntu-22.04 (R release and R devel)
17+
18+
## R CMD check results
919

10-
## R CMD CHECK Results
1120
0 errors | 0 warnings | 1 note
1221

1322
* checking for future file timestamps ... NOTE
1423
unable to verify current time
1524

16-
This NOTE is a transient network issue and not related to the package.
25+
This NOTE reflects the local machine's inability to reach a time server and is
26+
unrelated to the package.
27+
28+
## Reverse dependencies
29+
30+
Tplyr has no strong reverse dependencies (Depends/Imports/LinkingTo). Two
31+
packages list it under Suggests (clinify, logrx); this patch makes no
32+
user-facing API change and does not affect them.

tests/testthat/test-sort.R

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,44 @@ test_that("Sorting functions work correctly after refactoring", {
375375
expect_equal(nrow(b_t3), 3)
376376
expect_true("ord_layer_1" %in% names(b_t3))
377377
})
378+
379+
test_that("Count layer with an all-missing (NA) target sorts without warning (#213)", {
380+
# Regression test for #213: a group_count() target whose values are entirely
381+
# NA previously triggered `no non-missing arguments to max; returning -Inf`
382+
# and produced a non-finite (-Inf) ord_layer sort value. The bug lived in the
383+
# default `byfactor` path -- sort() drops the all-NA level, leaving an empty
384+
# lookup table, so max() was called on an empty set in R/sort.R.
385+
adsl <- data.frame(
386+
USUBJID = sprintf("S%02d", 1:4),
387+
TRT01PN = c(1, 1, 2, 2),
388+
DCSREAS = NA_character_,
389+
stringsAsFactors = FALSE
390+
)
391+
392+
# Every ord_layer_* sort value (whatever the by-structure) must be finite.
393+
all_ord_finite <- function(b) all(is.finite(unlist(b[, grepl("^ord_layer_", names(b)), drop = FALSE])))
394+
395+
# Default (byfactor) sort -- the affected path. Must build without a warning,
396+
# carry finite ordering values, and leave the counts intact (2 per group).
397+
t1 <- tplyr_table(adsl, TRT01PN) %>%
398+
add_layer(
399+
group_count(DCSREAS) %>%
400+
set_format_strings(f_str("xx", n))
401+
)
402+
expect_no_warning(b1 <- build(t1))
403+
expect_equal(nrow(b1), 1L)
404+
expect_true(all_ord_finite(b1))
405+
expect_equal(trimws(b1$var1_1), "2")
406+
expect_equal(trimws(b1$var1_2), "2")
407+
408+
# set_missing_count() relabeling of the NA row must also build cleanly.
409+
t2 <- tplyr_table(adsl, TRT01PN) %>%
410+
add_layer(
411+
group_count(DCSREAS) %>%
412+
set_format_strings(f_str("xx", n)) %>%
413+
set_missing_count(f_str("xx", n), Missing = NA)
414+
)
415+
expect_no_warning(b2 <- build(t2))
416+
expect_true(all_ord_finite(b2))
417+
expect_equal(b2$row_label1, "Missing")
418+
})

0 commit comments

Comments
 (0)