insightsengineering / tern

Table, Listings, and Graphs (TLG) library for common outputs used in clinical trials
https://insightsengineering.github.io/tern/
Other
77 stars 22 forks source link

[Bug]: format_count_fraction_fixed_dp #1191

Closed iaugusty closed 9 months ago

iaugusty commented 9 months ago

What happened?

A bug happened! format_count_fraction_fixed_dp(x), when x = c(denom,denom*(1/denom)) is not always denom (100%). This is as the check on the fraction : x[2] == 1 is not always true.

Replacing the check with signif(x[2],10^25) == 1, would resolve the bug.

library(tern)
library(dplyr)

sample <- 1000

xx <- data.frame(Ncol=1:sample)
xx <- xx %>% 
  rowwise() %>% 
  mutate(count=Ncol) %>% 
  mutate(pct = count*(1/Ncol)) %>% 
  mutate(fmt_tern = format_count_fraction_fixed_dp(c(count,pct))) %>% 
  mutate(check = pct == 1) %>% 
  mutate(check2 =signif(pct,10^25) == 1) %>% 
  mutate(fmtissue = ifelse(!check,"fmt not as expected","fmt as expected")) 

table(xx$fmtissue)

xx[xx$count %in% c(48,49,50),]

sessionInfo()

tern_0.9.3.9006

Relevant log output

No response

Code of Conduct

Contribution Guidelines

Security Policy

iaugusty commented 9 months ago

rather than signif, round should be used, round(x[2],10^25) == 1. signif(507/524,10^25) also results in 1

iaugusty commented 9 months ago

better option might be to use all.equal(x[2],1)

Melkiades commented 9 months ago

I tried all your options on your code and I still get 82 "fmt not as expected"

iaugusty commented 9 months ago
sample <- 1000

xx <- data.frame(Ncol=1:sample)
xx <- xx %>% 
  rowwise() %>% 
  mutate(count=Ncol) %>% 
  mutate(pct = count*(1/Ncol)) %>% 
  mutate(fmt_tern = format_count_fraction_fixed_dp(c(count,pct))) %>% 
  **mutate(check = all.equal(pct,1)) %>%** 
  mutate(fmtissue = ifelse(!check,"fmt not as expected","fmt as expected")) 

table(xx$fmtissue)
Melkiades commented 9 months ago
.is_equal_float <- function(x, y) {
  checkmate::assert_number(x)
  checkmate::assert_number(y)

  # Define a tolerance
  tolerance <- .Machine$double.eps

  # Check if x is close enough to y
  abs(x - y) < tolerance
}

This is better as all.equal produces a string in case of false