metrumresearchgroup / mrgsolve

Simulate from ODE-based population PK/PD and QSP models in R
https://mrgsolve.org
GNU General Public License v2.0
132 stars 36 forks source link

Annotation parsing #1109

Open FelicienLL opened 1 year ago

FelicienLL commented 1 year ago

Hi Kyle, Annotation parsing fails with nested (or multiple) brackets

mrgsolve:::parse_annot_line("SEX : 0 : sex (0 for male (default), 1 for female)")
#> $name
#> [1] "SEX"
#> 
#> $value
#> [1] "0"
#> 
#> $unit
#> [1] "0 for maledefault"
#> 
#> $options
#> [1] "."
#> 
#> $descr
#> [1] "sex, 1 for female)"
mrgsolve:::parse_annot_line("SEX : 0 : sex (0 for male default) (1 for female)")
#> $name
#> [1] "SEX"
#> 
#> $value
#> [1] "0"
#> 
#> $unit
#> [1] "1 for female"
#> 
#> $options
#> [1] "."
#> 
#> $descr
#> [1] "sex (0 for male default)"

This is due to this regular expression currently implemented.

https://github.com/metrumresearchgroup/mrgsolve/blob/c125cdb6731e1a9fed7f120ece214668be429bce/R/annot.R#L73

I don't know what would be the most appropriate regular expression, but instead I can propose this inelegant yet efficient function as a workaround to start with:

bracket_content <- function(string, open = "\\(", close = "\\)"){
  openings <- gregexpr(open, string)[[1]]
  closings <- gregexpr(close, string)[[1]]
  if(length(openings) != length(closings) || any(rev(closings) < openings)){
    stop("Invalid brackets specifications")
  }
  substr(x = string, start = openings[1], stop = closings[length(closings)])
}

bracket_content("sex (0 for male (default), 1 for female)")
#> [1] "(0 for male (default), 1 for female)"
bracket_content("sex (0 for male (default), 1 for female") # missing closing bracket
#> Error in bracket_content("sex (0 for male (default), 1 for female"): Invalid brackets specifications
bracket_content("sex (0 for male) (1 for female)") # multiple brackets
#> Error in bracket_content("sex (0 for male) (1 for female)"): Invalid brackets specifications
bracket_content("sex") # empty string
#> [1] ""
bracket_content("sex (0 male, 1 female) [and options]", "\\[", "\\]") # works with square brackets too
#> [1] "[and options]"

Created on 2023-08-22 with reprex v2.0.2

Best regards

Félicien