Skip to content

Commit 7c1e351

Browse files
authored
Merge pull request #172 from nlmixr2/vanco
Vanco
2 parents d74a4ee + 4e35b3d commit 7c1e351

29 files changed

+5805
-5584
lines changed

.github/workflows/R-CMD-check.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050

5151
- uses: r-lib/actions/setup-r-dependencies@v2
5252
with:
53+
cache-version: 3
5354
pak-version: devel
5455
extra-packages: |
5556
any::rcmdcheck

.github/workflows/pkgdown.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
use-public-rspm: true
3030

3131
- uses: r-lib/actions/setup-r-dependencies@v2
32+
cache-version: 2
3233
with:
3334
extra-packages: |
3435
any::pkgdown

.github/workflows/test-coverage.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323

2424
- uses: r-lib/actions/setup-r-dependencies@v2
2525
with:
26+
cache-version: 2
2627
pak-version: devel
2728
extra-packages: |
2829
any::covr

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: nonmem2rx
22
Type: Package
33
Title: 'nonmem2rx' Converts 'NONMEM' Models to 'rxode2'
4-
Version: 0.1.3
4+
Version: 0.1.3.9000
55
Maintainer: Matthew Fidler <matthew.fidler@gmail.com>
66
Authors@R: c(person("Matthew","Fidler", role = c("aut", "cre"), email = "matthew.fidler@gmail.com", comment=c(ORCID="0000-0001-8538-6691")),
77
person("Philip", "Delff", email = "philip@delff.dk",role = c("ctb")),
@@ -63,7 +63,7 @@ Suggests:
6363
rmarkdown,
6464
spelling
6565
Config/testthat/edition: 3
66-
RoxygenNote: 7.2.3
66+
RoxygenNote: 7.3.1
6767
Roxygen: list(markdown = TRUE)
6868
VignetteBuilder: knitr
6969
Language: en-US

NEWS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
# nonmem2rx (development version)
2+
3+
* Read all NONMEM files using latin1 encoding to allow single byte
4+
parser to work
5+
6+
* When lines in the NONMEM input dataset start with `#` they are now
7+
ignored.
8+
9+
* When all IDs are zero, NONMEM assumes restarting
10+
time gives different IDs; this is now reflected in NONMEM
11+
translation of IDs.
12+
13+
* With `linCmt()` parsing, expand the scope of conflicting parameters
14+
that will be renamed with an import.
15+
16+
* Added better parsing for `ELSE` where there is another `IF` on the
17+
next line.
18+
19+
* Prefixed conflicting `VP` with `rxm.` when `linCmt()` models to be
20+
more accommodating when importing linear compartment models.
21+
122
# nonmem2rx 0.1.3
223

324
* Added explicit requirement for rxode2 2.0.13

R/RcppExports.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
22
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
33

4-
fromNonmemToRxId <- function(nonmemId) {
5-
.Call(`_nonmem2rx_fromNonmemToRxId`, nonmemId)
4+
fromNonmemToRxId_ <- function(nonmemId, time) {
5+
.Call(`_nonmem2rx_fromNonmemToRxId_`, nonmemId, time)
66
}
77

R/asNonmem2rx.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ as.nonmem2rx <- function(model1, model2, compress=TRUE) {
8888
if (length(.w) == 1L) {
8989
.wcmt <- which(tolower(names(.nonmemData)) == "cmt")
9090
.wevid <- which(tolower(names(.nonmemData)) == "evid")
91-
if (length(.wcmt) == 1L && length(.wevid) == 1L) {
91+
if (length(.wcmt) == 1L && length(.wevid) == 1L) {e
9292
.minfo("merging 'dvid' with nlmixr2 'cmt' definition")
9393
.nonmemData[,.wcmt] <- ifelse(.nonmemData[, .wevid] != 0, .nonmemData[,.wcmt],
9494
length(.ui$mv0$state) + .nonmemData[, .w])

R/fromNonmemToRxId.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#' Converts to NONMEM id based on ID and time
2+
#'
3+
#' @param id identifier
4+
#' @param time time
5+
#' @return nothing, called for side effects
6+
#' @noRd
7+
#' @author Matthew L. Fidler
8+
fromNonmemToRxId <- function(id, time=NULL) {
9+
if (is.null(time)) {
10+
time <- as.double(seq_along(id))
11+
}
12+
.Call(`_nonmem2rx_fromNonmemToRxId_`, as.integer(id), as.double(time))
13+
}

R/linCmt.R

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
# comes from rxDerived regexp
3-
.linCmtParReg <- "^(?:(?:(?:V|Q|VP|VT|CLD)[[:digit:]])|KA|VP|VT|CLD|V|VC|CL|VSS|K|KE|KEL|Q|VT|(?:K[[:digit:]][[:digit:]])|AOB|ALPHA|BETA|GAMMA|A|B|C)$"
3+
.linCmtParReg <- "^(?:(?:(?:V|Q|VP|VT|CLD)[[:digit:]])|KA|VP|VT|CLD|V|VC|CL|VSS|K|KE|KEL|Q|VT|(?:K[[:digit:]][[:digit:]])|AOB|ALPHA|BETA|GAMMA|A|B|C).*$"
44

55
# translations to rxode2
66

@@ -80,14 +80,14 @@
8080
if (length(.w2) == 1) {
8181
names(.rep)[.w] <- paste0("V", .nonmem2rx$abbrevLin)
8282
} else if (length(.nonmem2rx$allVol) > 0) {
83-
.nchar <- vapply(.nonmem2rx$allVol, function(i){
83+
.nchar <- vapply(.nonmem2rx$allVol, function(i) {
8484
nchar(.nonmem2rx$allVol[i])
8585
}, integer(1), USE.NAMES=FALSE)
8686
.min <- min(.nchar)
8787
.w2 <- which(.nchar == .min)[1]
8888
names(.rep)[.w] <- .nonmem2rx$allVol[.w2]
8989
} else {
90-
stop("can't figure out volume for linCmt() model", call.=FALSE) #nocov
90+
stop("can't figure out volume for linCmt() model", call.=FALSE) #nocov
9191
}
9292
}
9393
}
@@ -97,9 +97,7 @@
9797
# specified and could be different
9898
.mv <- rxode2::rxModelVars(model)
9999
.lhs <- toupper(.mv$lhs)
100-
.rest <- setdiff(.lhs, names(.rep))
101-
.w <- which(.rest %in% toupper(.lhs))
102-
.lhsIn <- .mv$lhs[.w]
100+
.lhsIn <- .mv$lhs
103101
.lhsOut <- vapply(.lhsIn, function(x) {
104102
.up <- toupper(x)
105103
if (.up %in% names(.rep)) return(.rep[.up])
@@ -111,6 +109,7 @@
111109
.w <- which(.lhsIn != .lhsOut)
112110
.lhsIn <- .lhsIn[.w]
113111
.lhsOut <- .lhsOut[.w]
112+
114113
.ret <- eval(parse(text=paste0("rxode2::rxRename(model,",paste(paste0(.lhsOut, "=", .lhsIn), collapse=", "),")")))
115114
.ret <- rxode2::rxUiDecompress(.ret)
116115
.lstExpr <- .ret$lstExpr
@@ -149,5 +148,13 @@
149148
.fun0 <- as.call(c(list(quote(`{`)), .ini, .model))
150149
.fun <- function() {}
151150
body(.fun) <- .fun0
152-
.fun()
151+
.ret <- try(.fun(), silent=TRUE)
152+
if (inherits(.ret, "try-error")) {
153+
message(paste(deparse(.fun), collapse="\n"))
154+
stop("error parsing linCmt() translation:\n",
155+
attr(.ret, "condition")$message,
156+
"\ntranslation printed out so far",
157+
call.=FALSE)
158+
}
159+
.ret
153160
}

R/lst.R

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
return(NULL)
6161
}
6262
}
63-
return(.nmlst$section)
63+
.nmlst$section
6464
}
6565

6666
.nmlstVersion <- function(line) {
@@ -232,7 +232,7 @@
232232
}
233233
return(NULL)
234234
}
235-
return(TRUE)
235+
TRUE
236236
}
237237

238238

@@ -259,7 +259,7 @@
259259
}
260260
return(NULL)
261261
}
262-
return(TRUE)
262+
TRUE
263263
}
264264

265265
.prepareEst <- function() {
@@ -371,9 +371,7 @@
371371
if (is.null(.nmlstObj(line))) return(NULL)
372372
if (is.null(.nmlstEst(line))) return(NULL)
373373
if (is.null(.nmlstCov(line))) return(NULL)
374-
375-
return(NULL)
376-
374+
NULL
377375
}
378376

379377
.resetLst <- function(strictLst) {
@@ -421,7 +419,7 @@ nmlst <- function(file, strictLst=FALSE) {
421419
# run time
422420
# nmtran message
423421
if (length(file) == 1L) {
424-
.lst <- suppressWarnings(readLines(file))
422+
.lst <- suppressWarnings(readLines(file, encoding="latin1"))
425423
} else {
426424
.lst <-file
427425
}

R/nminfo.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ nminfo <- function(file,
146146
if (!file.exists(.lstFile)) {
147147
if (file.exists(file)) {
148148
if (verbose) .minfo("seeing if file argument is actually lst file")
149-
.fileLines <- suppressWarnings(readLines(file))
149+
.fileLines <- suppressWarnings(readLines(file, encoding="latin1"))
150150
.w <- which(regexpr("^( *NM-TRAN +MESSAGES *| *1NONLINEAR *MIXED|License +Registered +to: +)", .fileLines)!=-1)
151151
if (length(.w) == 0L) {
152152
.wpro <- which(regexpr("^ *[$][Pp][Rr][Oo]", .fileLines) != -1)
@@ -173,7 +173,7 @@ nminfo <- function(file,
173173
.nmlst$section <- .nmlst.tere
174174
.nmlst$tereOnly <- TRUE
175175
if (length(.lstFile) == 1L) {
176-
.l <- suppressWarnings(readLines(.lstFile))
176+
.l <- suppressWarnings(readLines(.lstFile, encoding="latin1"))
177177
} else {
178178
.l <- .lstFile
179179
}
@@ -220,7 +220,7 @@ nminfo <- function(file,
220220
# lonely control stream?
221221
if (file.exists(file)) {
222222
if (verbose) .minfo("is file actually control stream")
223-
.fileLines <- suppressWarnings(readLines(file))
223+
.fileLines <- suppressWarnings(readLines(file, encoding="latin1"))
224224
.wpro <- which(regexpr("^ *[$][Pp][Rr][Oo]", .fileLines) != -1)
225225
if (length(.wpro) != 0L) {
226226
.control <- .fileLines[seq(.wpro[1], length(.fileLines))]
@@ -239,7 +239,7 @@ nminfo <- function(file,
239239
.ctl <- paste0(.base, mod)
240240
if (verbose) .minfo("looking for control stream")
241241
if (file.exists(.ctl)) {
242-
.fileLines <- suppressWarnings(readLines(file))
242+
.fileLines <- suppressWarnings(readLines(file, encoding="latin1"))
243243
.wpro <- which(regexpr("^ *[$][Pp][Rr][Oo]", .fileLines) != -1)
244244
if (length(.wpro) != 0L) {
245245
.control <- .fileLines[seq(.wpro[1], length(.fileLines))]

R/nmtab.R

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
#' Read nonmem table file
22
#'
3-
#'
3+
#'
44
#' @param file file name to read the results from
55
#' @param ... other parameters passed to `data.table::fread`
66
#' @return data frame of the read table
7-
#' @export
7+
#' @export
88
#' @author Philip Delff, Matthew L. Fidler
99
#' @examples
1010
#' nmtab(system.file("mods/cpt/runODE032.csv", package="nonmem2rx"))
11-
nmtab <- function (file, ...)
11+
nmtab <- function (file, ...)
1212
{
1313
checkmate::assertFileExists(file)
1414
TABLE <- NULL
1515
NMREP <- NULL
16-
colnames <- readLines(file, n=2)[2]
16+
colnames <- readLines(file, n=2, encoding="latin1")[2]
1717
if (grepl(", *OMEGA\\( *1 *, *1\\)", colnames)) {
1818
col.names <- gsub(" ", "",strsplit(colnames, " +,")[[1]])
1919
dt1 <- fread(file, fill = TRUE, header = TRUE, skip = 1,
2020
...)
2121
dt1 <- dt1[,seq_along(col.names), with=FALSE]
2222
setnames(dt1, col.names)
2323
} else {
24-
dt1 <- fread(file, fill = TRUE, header = TRUE, skip = 1,
24+
dt1 <- fread(file, fill = TRUE, header = TRUE, skip = 1,
2525
...)
2626
}
2727
cnames <- colnames(dt1)
2828
if (length(cnames) == 0L) return(NULL)
29-
dt1[grep("^TABLE", as.character(get(cnames[1])), invert = FALSE,
29+
dt1[grep("^TABLE", as.character(get(cnames[1])), invert = FALSE,
3030
perl = TRUE), `:=`(TABLE, get(cnames[1]))]
3131
dt1[, `:=`(NMREP, cumsum(!is.na(TABLE)) + 1)]
3232
dt1[, `:=`(TABLE, NULL)]
33-
dt1 <- dt1[grep("^ *[[:alpha:]]", as.character(get(cnames[1])),
33+
dt1 <- dt1[grep("^ *[[:alpha:]]", as.character(get(cnames[1])),
3434
invert = TRUE, perl = TRUE)]
3535
cols.dup <- duplicated(colnames(dt1))
3636
if (any(cols.dup)) {
37-
.minfo(paste0("Cleaned duplicated column names: ",
37+
.minfo(paste0("Cleaned duplicated column names: ",
3838
paste(colnames(dt1)[cols.dup], collapse = ",")))
3939
dt1 <- dt1[, unique(cnames), with = FALSE]
4040
}
4141
cnames <- colnames(dt1)
4242
dt1[, `:=`((cnames), lapply(.SD, as.numeric))]
4343
dt1 <- as.data.frame(dt1)
44-
return(dt1)
44+
dt1
4545
}

R/nonmem2rx.R

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,11 @@ nonmem2rx <- function(file, inputData=NULL, nonmemOutputDir=NULL,
744744
.advan5odes(),
745745
"\n})",
746746
"}")
747-
.fun <- eval(parse(text=.txt))
747+
.fun <- try(eval(parse(text=.txt)), silent=TRUE)
748+
if (inherits(.fun, "try-error")) {
749+
message(.txt)
750+
stop("error translating NONMEM, model translation so far echoed above", call.=FALSE)
751+
}
748752
.rx <- .fun()
749753
.rx <- .getLinCmtModel(.rx, advan=.nonmem2rx$advan, trans=.nonmem2rx$trans)
750754
.update <- FALSE
@@ -778,7 +782,7 @@ nonmem2rx <- function(file, inputData=NULL, nonmemOutputDir=NULL,
778782
.in <-c(.mv$params, .mv$state, .mv$lhs)
779783
.w <- which(vapply(.r,
780784
function(v) {
781-
return(v %in% .in)
785+
v %in% .in
782786
}, logical(1), USE.NAMES=FALSE))
783787
if (length(.w) > 0) {
784788
.r <- .r[.w]

R/readCov.R

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
11
#' Read in data file
2-
#'
2+
#'
33
#' @inheritParams nmtab
4-
#'
4+
#'
55
#' @return A matrix with covariance step from NONMEM
6-
#'
6+
#'
77
#' @export
8-
#'
8+
#'
99
#' @author Philip Delff and Matthew L. Fidler
10-
#'
10+
#'
1111
#' @examples
12-
#'
12+
#'
1313
#' nmcov(system.file("mods/cpt/runODE032.cov", package="nonmem2rx"))
1414
nmcov <- function (file, ...) {
1515
checkmate::assertFileExists(file)
1616
TABLE <- NULL
1717
NMREP <- NULL
1818
NAME <- NULL
19-
colnames <- readLines(file, n=2)[2]
19+
colnames <- readLines(file, n=2, encoding = "latin1")[2]
2020
if (grepl(", *OMEGA\\( *1 *, *1\\)", colnames)) {
2121
# in this case the NAME also has commas
22-
lines <- readLines(file)
22+
lines <- readLines(file, encoding="latin1")
2323
lines <- gsub("(OMEGA|SIGMA)[(]([0-9]+),([0-9]+)[)]", "\\1\\2AAAAAAAAA\\3", lines)
2424
file2 <- tempfile()
2525
writeLines(lines, file2)
26-
dt1 <- fread(file2, fill = TRUE, header = TRUE, skip = 1, sep=",",
26+
dt1 <- fread(file2, fill = TRUE, header = TRUE, skip = 1, sep=",",
2727
...)
2828
unlink(file2)
2929
dt1$NAME <- gsub("[A]([0-9]+)AAAAAAAAA([0-9]+)", "A(\\1,\\2)", dt1$NAME)
3030
setnames(dt1, gsub("[A]([0-9]+)AAAAAAAAA([0-9]+)", "A(\\1,\\2)", names(dt1)))
3131
} else {
32-
dt1 <- fread(file, fill = TRUE, header = TRUE, skip = 1,
32+
dt1 <- fread(file, fill = TRUE, header = TRUE, skip = 1,
3333
...)
3434
}
3535
cnames <- colnames(dt1)
36-
dt1[grep("^TABLE", as.character(get(cnames[1])), invert = FALSE,
36+
dt1[grep("^TABLE", as.character(get(cnames[1])), invert = FALSE,
3737
perl = TRUE), `:=`(TABLE, get(cnames[1]))]
3838
dt1[, `:=`(NMREP, cumsum(!is.na(TABLE)) + 1)]
3939
dt1[, `:=`(TABLE, NULL)]
@@ -48,5 +48,5 @@ nmcov <- function (file, ...) {
4848
dn <- dimnames(dt1)
4949
dn[[1]] <- dn[[2]]
5050
dimnames(dt1) <- dn
51-
return(dt1)
51+
dt1
5252
}

0 commit comments

Comments
 (0)