Shuanghe
★    

Spain,
2019-04-03 17:41

Posting: # 20120
Views: 437
 

 Possible bug in bootf2BCA [Software]

Hi All,

Detlew mentioned bootf2BCA for bootstrap f2 method, written by Aleksander Mendyk, the author of another tool PhEq_bootstrap. I have been using both programs for some time now and I just noticed that there might be an error in the bootf2BCA when you want to use only 1 time point after >=85% release, according to EMA's rule.

For example, for the following data (mean value from sample data of bootf2BCA), according to EMA's rule, only 1 time point after 85% should be used, so the cutting point is 90 min; data of 180 min should not be used. According to US FDA's rule agreed by many, both test and reference should reach >=85% so the cutting point is 180 min. In this case, use all data point.

Time  Test   Ref
30    40.3   34.9
60    67.1   59.5
90    87.0   79.3
180   97.7   95.1


However, if you set my85auto_rule = 1 in the function (CLI version) or choose 1 profile in GUI version, the report file shows that all f2 were actually calculated according to US FDA's rule, same as if you set my85auto_rule = 2.

The rule, as far as I understood the code, is defined as a function between line 84 and 112 in CLI version of the program and copied below (I added some spaces and comments to make the code easier to read. Original source file contains almost no comment and is hard to read as Detlew warned in his post).

#function to employ a rule that no more than one point after 85% dissolution should be taken into account when calculating f2
prepare_profiles_cutoff_85_percent <- function(data_matrix){
  res_data  <- matrix()
  lk_stop   <- nrow(data_matrix)
  is_second <- FALSE
   
  for(i in 1:nrow(data_matrix)){
    if(my85auto_rule == 1){
      if((data_matrix[i, 1] >= 85) || (data_matrix[i, 2] >= 85)){
        if (is_second){
          lk_stop <- i
          break
        }else{
          is_second <- TRUE
        }
      } # end t >= 85 || r >= 85 if condition
    }else{ # for my85auto_rule not equal to 1. not relevant to discussion here
      if((data_matrix[i, 1] >= 85) && (data_matrix[i, 2] >= 85)){
        if (is_second){
          lk_stop <- i
          break
        }else{
          is_second <- TRUE
        }
      } # end t >= 85 && r >= 85 if condition     
    } # end for my85auto_rule !=1
  } # end for loop
 
  res_data <- data_matrix[1:lk_stop, ]    
  return(res_data)
}

Using the table above as an example and set my85auto_rule = 1 in the function (so forget the else expression where this value is not 1), my understanding to evaluate for loop is as follows, though I’m not sure the purpose of the variable is_second here:

  1. Loop start, i=1, if condition ((data_matrix[i,1]>=85)||(data_matrix[i,2]>=85)) is false, so expression within {} is skipped.
  2. Loop over, i=2, the same.
  3. Loop over, i=3, if condition((data_matrix[i,1]>=85)||(data_matrix[i,2]>=85)) is true because test release 87% at 90 min, evaluate expression within {}.

    1. if condition is false because variable is_second is false by default
    2. expression in else is evaluated so this variable became true (by is_second <- TRUE).

  4. Looping over, i=4, if condition ((data_matrix[i,1]>=85)||(data_matrix[i,2]>=85)) is true and if condition (is_second) is also true, so variable 1k_stop gets value 4 from i. loop break.
  5. Therefore, after for loop, the res_data is data_matrix[1:4, ], including 180 min data point, which might explain what happened.

Is above the correct evaluation in R? Or there's something wrong in step 3?

I changed the for loop code to the following and it seems it works.
prepare_profiles_cutoff_85_percent <- function(data_matrix){
  res_data  <- matrix()
  lk_stop   <- nrow(data_matrix)
  is_second <- FALSE

  for(i in 1:nrow(data_matrix)){
    if(my85auto_rule == 1){
      if((data_matrix[i, 1] >= 85)||(data_matrix[i, 2] >= 85)){
        lk_stop <- i
        break
      }
    }else{
  ... i didn't change the rest since I only need to use EMA's rule at the moment.
 }


So what's the purpose of variable is_second?

Is there anyone else noticed the same problem, or any other issues when using the program?

All the best,
Shuanghe
d_labes
★★★

Berlin, Germany,
2019-04-03 19:42

@ Shuanghe
Posting: # 20121
Views: 381
 

 Bug in bootf2BCA - Open source rulez!

Dear Shuanghe!

Congratulation :clap:! Mastering that code!
As I stated earlier: The source code is hard to read, nearly no comments at all.

But I'm quite sure that your analysis of the code is totally correct.
Wouldn't be possible if the code was not open source.

What the purpose of the variable is_second was or should be one can only speculate about.
Don't think too much about that.

Regards,

Detlew
Shuanghe
★    

Spain,
2019-05-06 09:39

@ d_labes
Posting: # 20272
Views: 126
 

 newer version of bootf2BCA

Hi all,

When I found the bug I contacted the author and I just got feedback from him that the newer version has just been uploaded to the sourceforge. I don't have time to try it out yet but in case someone's interested, here's the link.


To Detlew,

» Wouldn't be possible if the code was not open source.
Yep! Open source rules! :-D

All the best,
Shuanghe
Activity
 Thread view
Bioequivalence and Bioavailability Forum |  Admin contact
19,490 posts in 4,135 threads, 1,335 registered users;
online 9 (0 registered, 9 guests [including 4 identified bots]).
Forum time (Europe/Vienna): 19:49 CEST

No rational argument will have a rational effect on a man
who does not want to adopt a rational attitude.    Karl R. Popper

The BIOEQUIVALENCE / BIOAVAILABILITY FORUM is hosted by
BEBAC Ing. Helmut Schütz
HTML5