Skip to content

Commit d799de0

Browse files
Kyun-Seop Baecran-robot
authored andcommitted
version 0.8.0
1 parent 9eb94ca commit d799de0

File tree

9 files changed

+124
-44
lines changed

9 files changed

+124
-44
lines changed

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: wnl
2-
Version: 0.7.3
2+
Version: 0.8.0
33
Title: Minimization Tool for Pharmacokinetic-Pharmacodynamic Data
44
Analysis
55
Description: This is a set of minimization tools (maximum likelihood estimation and least square fitting) to solve examples in the Johan Gabrielsson and Dan Weiner's book "Pharmacokinetic and Pharmacodynamic Data Analysis - Concepts and Applications" 5th ed. (ISBN:9198299107). Examples include linear and nonlinear compartmental model, turn-over model, single or multiple dosing bolus/infusion/oral models, allometry, toxicokinetics, reversible metabolism, in-vitro/in-vivo extrapolation, enterohepatic circulation, metabolite modeling, Emax model, inhibitory model, tolerance model, oscillating response model, enantiomer interaction model, effect compartment model, drug-drug interaction model, receptor occupancy model, and rebound phenomena model.
@@ -12,5 +12,5 @@ NeedsCompilation: no
1212
LazyLoad: yes
1313
Repository: CRAN
1414
URL: https://cran.r-project.org/package=wnl
15-
Packaged: 2023-04-17 21:02:37 UTC; Kyun-SeopBae
16-
Date/Publication: 2023-04-25 03:30:03 UTC
15+
Packaged: 2024-02-22 05:56:36 UTC; Kyun-SeopBae
16+
Date/Publication: 2024-02-22 06:20:02 UTC

MD5

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
dcd531c376e9100eee542e50ae21b588 *DESCRIPTION
1+
b4ec2498de8b0b66680530cb18261254 *DESCRIPTION
22
390de0872c5e034f3bb65922b8b78051 *NAMESPACE
3-
83d6bb93ca7f2ebe336d3d1c70e6d5de *R/BasicUtil.R
3+
afc57c175ab7a762077e71ac3effeed1 *R/BasicUtil.R
44
ba1255e411249f4db6f2caa66ee30cfe *R/Comp1.R
55
6ee187dd007ec9a4d1193101fb331c53 *R/EnvObj.R
66
cf5ef0c31a8433b8f966716f203471b9 *R/ExpandDH.R
7-
82c430639b2aec87a2d8257e1ed87b19 *R/Objs.R
8-
f7a61f78602501325418063cc00df4d4 *R/Secondary.R
7+
a3c994e66e093b3202e7ab69da35fc93 *R/Objs.R
8+
8f65358ebfbc3a2450251fc0f686d17b *R/Secondary.R
99
5d9a05e422d4e7fd3413f288aaea93a8 *R/SolComp2.R
1010
7791bb80ef7ff7935d783d3550d08bb7 *R/SolComp3.R
1111
b801ef09ac2e1d9c931f1d08fe4a6b90 *R/cmpChi.R
1212
752433b1b66c620b33c3def811efdc8f *R/dx.R
1313
9bf4095904c0bf59982cb603c2b69e5c *R/hSkew.R
1414
ca032758dcb79150beac3ef4564b7cb8 *R/nComp.R
15-
6c3ab16618f11b24fa73adf2d1083d1e *R/nlr.R
15+
b087399546d4cedaf961d69ceb6238d8 *R/nlr.R
1616
969cb4bf5cab158d9f4b9fbd260ae4e1 *R/pComp.R
1717
29c541a8d30080132cd50a98484542db *R/pProf.R
1818
3a85a468ae0dc2bbb899524ea01feccf *R/sysdata.rda
1919
1c9e1b28728c0f1fc96017efc560b0d6 *R/wnl5.R
20-
f9e97cf825c853b1c7161b06fb90cc50 *inst/NEWS.Rd
20+
96768ba9460fc589c2a4a40084325289 *inst/NEWS.Rd
2121
75463c4d3bd42432719b597f93dd859d *inst/doc/Compartment-vignette.pdf
22-
13988a98e0e282530ebd7bdcf151ab0b *inst/doc/wnl-manual.pdf
22+
00ccc7e8b63db769da280561f0329a64 *inst/doc/wnl-manual.pdf
2323
57010db082832f52da4856e4b3521524 *man/BasicUtil.Rd
2424
f9ab397c3e89d4acba0f7c5f06e91923 *man/Comp1.Rd
2525
6c87b1f721849279be48c7474dee83b5 *man/DAT.Rd
@@ -34,7 +34,7 @@ e1e7543809d439770aa7d1cb6e897193 *man/dx.Rd
3434
ee0ea2d2db69f309039e2d70a791ac0a *man/e.Rd
3535
d60a1682e9d37ff616877f1ce4738665 *man/hSkew.Rd
3636
62aedc1f108c168426e5402b454b82e1 *man/nComp.Rd
37-
4990a914b5d7730be858fd9462f9e750 *man/nlr.Rd
37+
ae6d73065d75619d1a1a83086569cdf2 *man/nlr.Rd
3838
3a1b70982f3cf42a7bd0a912b81ca182 *man/pComp.Rd
3939
2c87a9fd98a811d39fd3431176c7b46e *man/pProf.Rd
4040
8640ba18696633870f706cd63f6d440c *man/wnl-package.Rd

R/BasicUtil.R

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,14 @@ nHessian = function(fx, x)
164164
return(H)
165165
}
166166

167-
g2inv = function(A, Augmented=FALSE, eps=1e-8)
167+
g2inv = function(A, eps=1e-8)
168168
{
169169
idx = abs(diag(A)) > eps
170170
p = sum(idx, na.rm=T)
171-
p0 = ifelse(Augmented, p - 1, p)
172-
if (p == 0 | p0 < 1) { A[, ] = 0 ; attr(A, "rank") = 0 ; return(A) }
171+
if (p == 0) { M[, ] = 0 ; attr(M, "rank") = 0 ; return(M) }
173172
B = A[idx, idx, drop=F]
174-
175173
r = 0
176-
for (k in 1:p0) {
174+
for (k in 1:p) {
177175
d = B[k, k]
178176
if (abs(d) < eps) { B[k, ] = 0 ; B[, k] = 0 ; next }
179177
B[k, ] = B[k, ]/d
@@ -188,10 +186,11 @@ g2inv = function(A, Augmented=FALSE, eps=1e-8)
188186
B[k, k] = 1/d
189187
}
190188

191-
A[!idx, !idx] = 0
192-
A[idx, idx] = B
193-
attr(A, "rank") = r
194-
return(A)
189+
M = matrix(0, nrow=NCOL(A), ncol=NROW(A))
190+
M[1:r, 1:r] = B[1:r, 1:r]
191+
attr(M, "rank") = r
192+
193+
return(M)
195194
}
196195

197196
Hougaard = function(J, H, ssq)

R/Objs.R

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,46 @@
1+
#ObjEst = function(vPara)
2+
#{
3+
# b0 = exp(vPara - e$alpha)
4+
# vPara = vector(length=e$nPara0)
5+
# vPara[e$toEst] = b0/(b0 + 1)*(e$UB - e$LB) + e$LB
6+
# if (e$fix[1] != 0) vPara[e$fix] = e$IE0[e$fix]
7+
# return(e$Obj(vPara))
8+
#}
9+
110
ObjEst = function(vPara)
211
{
312
b0 = exp(vPara - e$alpha)
413
vPara = b0/(b0 + 1)*(e$UB - e$LB) + e$LB
514
return(e$Obj(vPara))
615
}
716

8-
ObjDef = function(vPara) # Default Obj for Covariance Step (original obj)
17+
ObjDef = function(vPara0) # Default Obj for Covariance Step (original obj)
918
{
10-
Fi = e$Fx(vPara[1:e$nTheta])
19+
vPara = vector(length=e$nPara0)
20+
vPara[e$toEst] = vPara0
21+
if (e$fix[1] != 0) vPara[e$fix] = e$IE0[e$fix]
22+
23+
Fi = e$Fx(vPara[1:e$nTheta0])
1124
Ri = e$Y - Fi
1225
e$Fi = Fi
1326

1427
if (e$Error == "A") {
15-
Ci = rep(vPara[e$SGindex], e$nRec)
28+
Ci = rep(vPara[e$SGindex0], e$nRec)
1629
} else if (e$Error == "POIS") {
17-
Ci = vPara[e$SGindex]*Fi # Caution on Fi is zero
30+
Ci = vPara[e$SGindex0]*Fi # Caution on Fi is zero
1831
Ci[Fi == 0] = 1 # Weight cannot be calculated with zero values
1932
Ri[Fi == 0] = 0
2033
} else if (e$Error == "P") {
21-
Ci = vPara[e$SGindex]*Fi*Fi # Caution on Fi is zero
34+
Ci = vPara[e$SGindex0]*Fi*Fi # Caution on Fi is zero
2235
Ci[Fi == 0] = 1 # Weight cannot be calculated with zero values
2336
Ri[Fi == 0] = 0
2437
} else if (e$Error == "C") {
25-
Ci = rep(vPara[e$SGindex[1]], e$nRec) + vPara[e$SGindex[2]]*Fi*Fi
38+
Ci = rep(vPara[e$SGindex0[1]], e$nRec) + vPara[e$SGindex0[2]]*Fi*Fi
2639
# } else if (e$Error == "CFA") { # Additive fixed propertional
2740
# Ci = (e$FASD + sqrt(vPara[e$SGindex[1]])*Fi)^2
2841
} else if (e$Error == "S") {
29-
Si = e$Sx(vPara[1:e$nTheta])
30-
Ci = vPara[e$SGindex]*Si
42+
Si = e$Sx(vPara[1:e$nTheta0])
43+
Ci = vPara[e$SGindex0]*Si
3144
Ci[Si == 0] = 1 # Weight cannot be calculated with zero values
3245
Ri[Si == 0] = 0
3346
}

R/Secondary.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Secondary = function(Formula, PE, COV)
44
gr0 = deriv(Formula, names(PE), function.arg=names(PE), func=TRUE)
55
gr1 = do.call("gr0", as.list(PE))
66
PE2 = gr1[1]
7-
gr2 = attr(gr1,"gradient")
7+
gr2 = attr(gr1,"gradient")
88
SE2 = sqrt(gr2 %*% COV %*% t(gr2))
9-
CV2 = SE2/PE2*100
9+
CV2 = SE2/PE2*100
1010
Result = c(PE2, SE2, CV2)
1111
names(Result) = c("PE", "SE", "RSE")
1212
return(Result)

R/nlr.R

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames, SecForms, Method="L-BFGS-B", Sx, conf.level=0.95, k)
1+
nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames, SecForms, Method="L-BFGS-B", Sx, conf.level=0.95, k, fix=0)
22
{
33
# e = new.env(parent=globalenv()) # environment should exist before call this function
44
t1 = Sys.time()
@@ -10,14 +10,13 @@ nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames,
1010
e$nRec = nrow(e$Y)
1111
} else {
1212
if (!("DV" %in% colnames(Data))) stop("Data should have 'DV' column.")
13-
if (mean(abs(Data[, "DV"])) < 1e-6 | mean(abs(Data[,"DV"])) > 1e6) warning("DV is too large or too small. Rescale it.")
13+
if (mean(abs(Data[, "DV"])) < 1e-6 | mean(abs(Data[, "DV"])) > 1e6) warning("DV is too large or too small. Rescale it.")
1414
e$Y = Data[, "DV"] # Observation values, Data should have "DV" column.
1515
e$nRec = length(e$Y)
1616
if (sum(is.na(Data[, "DV"])) > 0) stop("DV column should not have NAs.")
1717
}
1818

1919
if (length(pNames) != length(IE)) stop("pNames and IE should match.")
20-
2120
e$pNames = pNames # parameter names in the order of Fx arguments
2221
e$IE = IE # initial estimate of Fx arguments
2322
e$nTheta = length(IE)
@@ -86,10 +85,37 @@ nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames,
8685
# e$Ci = cbind(rep(SG1*SG1, e$nRec), rep(SG2*SG2, e$nRec))
8786
# e$SumLogCi = sum(log(e$Ci))
8887
}
88+
89+
e$IE0 = e$IE
90+
e$nPara0 = e$nPara
91+
e$nTheta0 = e$nTheta
92+
e$SGindex0 = e$SGindex
93+
e$fix0 = fix
94+
e$fix = e$fix0
95+
e$toEst = which(!(1:e$nPara %in% e$fix))
96+
e$pNames= e$pNames[e$toEst]
97+
e$IE = e$IE[e$toEst]
98+
e$LB = e$LB[e$toEst]
99+
e$UB = e$UB[e$toEst]
100+
e$nTheta = sum(1:e$nTheta %in% e$toEst)
101+
e$nPara = length(e$toEst)
102+
e$nEps = sum((1 + e$nTheta0):e$nPara0 %in% e$toEst)
103+
if (e$nEps > 0) {
104+
e$SGindex = (e$nTheta + 1):(e$nTheta + e$nEps) # index of error variance(s)
105+
} else {
106+
e$SGindex = 0
107+
}
108+
e$alpha = e$alpha[e$toEst]
109+
89110
e$r = optim(rep(0.1, e$nPara), ObjEst, method=Method)
90111
e$PE = exp(e$r$par - e$alpha)/(exp(e$r$par - e$alpha) + 1)*(e$UB - e$LB) + e$LB
91112

113+
# e$PE0 = vector(length=e$nPara0)
114+
# e$PE0[e$toEst] = e$PE
115+
# e$PE0[e$fix] = e$IE0[e$fix]
116+
# e$InvCov = hessian(e$Obj, e$PE0)/2 # FinalEst from EstStep()
92117
e$InvCov = hessian(e$Obj, e$PE)/2 # FinalEst from EstStep()
118+
e$InvCov = e$InvCov
93119
e$Cov = try(solve(e$InvCov), silent=T)
94120
if (!is.matrix(e$Cov)) {
95121
e$Cov = g2inv(e$InvCov)
@@ -109,6 +135,19 @@ nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames,
109135
e$Correl = cov2cor(e$Cov)
110136
e$EigenVal = eigen(e$Correl)$values
111137

138+
## Hougaard Skewness
139+
if (e$Error == "A") {
140+
e$PE0 = vector(length=e$nPara0)
141+
e$PE0[e$toEst] = e$PE
142+
e$PE0[e$fix] = e$IE0[e$fix]
143+
144+
e$J = nGradient(e$Fx, e$PE0[1:e$nTheta0])
145+
e$H = nHessian(e$Fx, e$PE0[1:e$nTheta0])
146+
e$HouSkew = Hougaard(e$J, e$H, e$PE0[e$SGindex0])
147+
names(e$HouSkew) = pNames
148+
}
149+
150+
## SE
112151
if (e$SGindex[1] > 0) {
113152
e$PE = c(e$PE, sqrt(e$PE[e$SGindex]))
114153
e$SE = c(e$SE, e$SE[e$SGindex]/2/sqrt(e$PE[e$SGindex])) # Delta method, See Wackerly p484, gr = (x^0.5)' = 0.5x^(-0.5), gr^2 = 1/(4*x)
@@ -158,13 +197,6 @@ nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames,
158197
e$nRec = sum(e$Y != -1)
159198
}
160199

161-
## Hougaard Skewness
162-
if (e$Error == "A") {
163-
e$J = nGradient(e$Fx, e$PE[1:e$nTheta])
164-
e$H = nHessian(e$Fx, e$PE[1:e$nTheta])
165-
e$HouSkew = Hougaard(e$J, e$H, e$PE[e$SGindex])
166-
}
167-
168200
## Likelihood Profile
169201
cAdd = e$nRec*log(2*pi)
170202
nRes = 51
@@ -255,14 +287,35 @@ nlr = function(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames,
255287

256288
options(warn=0) # end of calling uniroot
257289

290+
if (e$SGindex[1] > 0) {
291+
e$LI = cbind(e$LI, sqrt(e$LI[, e$SGindex]))
292+
colnames(e$LI) = colnames(e$Est)[1:(e$nPara + length(e$SGindex))]
293+
}
294+
295+
if (!missing(SecNames)) {
296+
nSec = length(SecNames)
297+
tRes = matrix(nrow=2, ncol=nSec)
298+
colnames(tRes) = SecNames
299+
rownames(tRes) = c("LL", "UL")
300+
for (i in 1:nSec) {
301+
fx2 = deriv(SecForms[[i]], e$pNames, function.arg=e$pNames, func=TRUE)
302+
tv1 = do.call("fx2", as.list(e$LI[1, e$pNames]))
303+
tv2 = do.call("fx2", as.list(e$LI[2, e$pNames]))
304+
tRes[, i] = sort(c(tv1, tv2))
305+
}
306+
e$LI = cbind(e$LI, tRes)
307+
}
308+
colnames(e$LI) = colnames(e$Est)
309+
attr(e$LI, "k") = exp(logk)
310+
258311
e$mOFV = matrix(nrow=nRes, ncol=e$nPara)
259312
e$mPar = matrix(nrow=nRes, ncol=e$nPara)
260313
colnames(e$mOFV) = e$pNames[1:e$nPara]
261314
colnames(e$mPar) = e$pNames[1:e$nPara]
262315
for (j in 1:e$nPara) {
263316
e$mPar[, j] = seq(e$mParB[1, j], e$mParB[2, j], length.out=nRes)
264317
for (i in 1:nRes) {
265-
tPar = e$PE
318+
tPar = e$PE[1:e$nPara0]
266319
tPar[j] = e$mPar[i, j]
267320
e$mOFV[i, j] = cAdd + e$Obj(tPar) # -2LL
268321
}

inst/NEWS.Rd

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
\name{NEWS}
22
\title{News for Package \pkg{wnl}}
3-
3+
\section{Version 0.8.0 (2024-02-22)}{
4+
\itemize{
5+
\item{g2inv utility function is revised to handle non-square matrix.}
6+
}
7+
}
48

59
\section{Version 0.7.3 (2023-04-25)}{
610
\itemize{
7-
\item{If default k value in nlr() is adjusted.}
11+
\item{Default k value in nlr() is adjusted.}
812
}
913
}
1014

inst/doc/wnl-manual.pdf

5.69 KB
Binary file not shown.

man/nlr.Rd

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ It performs nonlinear regression usually for pharmacokinetic and pharmacodynamic
66
}
77
\usage{
88
nlr(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames, SecForms,
9-
Method="L-BFGS-B", Sx, conf.level=0.95, k)
9+
Method="L-BFGS-B", Sx, conf.level=0.95, k, fix=0)
1010
}
1111
\arguments{
1212
\item{Fx}{Function for structural model. It should return a vector of the same length to observations.}
@@ -23,6 +23,7 @@ nlr(Fx, Data, pNames, IE, LB, UB, Error="A", ObjFx=ObjDef, SecNames, SecForms,
2323
\item{Sx}{Scale function. This is usually the inverse of weight. It should return the same length(nrow) of Y. When Error="S", Scale function should be provided as \code{Sx}.}
2424
\item{conf.level}{Confidence level for confidence interval}
2525
\item{k}{1/k likelihood interval(LI) will be provided. Currently recommended value is exp(qf(1 - alpha, 1, nRec-nPara)/2) + 1.}
26+
\item{fix}{indices of parameters to fix}
2627
}
2728
\details{
2829
This uses scaled transformed parameters and environment \code{e} internally.
@@ -75,5 +76,15 @@ This uses scaled transformed parameters and environment \code{e} internally.
7576
print(paste("## ID =", i, "##"))
7677
print(Res)
7778
}
79+
80+
# Another example from radioimmunoassay(RIA)
81+
d1 = data.frame(conc = c(200, 100, 50, 25, 12.5, 6.25, 3.125, 0),
82+
DV = c(1.78, 1.5, 1.17, 0.74, 0.51, 0.31, 0.19, 0.04))
83+
84+
PRED = function(TH) TH[1] + TH[2]*d1$conc^TH[4]/(TH[3]^TH[4] + d1$conc^TH[4])
85+
Scale = function(TH) 1/(PRED(TH) - (TH[1] + TH[2])/2)^2
86+
87+
nlr(PRED, d1, pNames=c("R0", "Rmax", "RC50", "Hill"), IE=c(0.1, 3, 50, 1),
88+
Error="S", Sx=Scale)
7889
}
7990
\keyword{Maximum Likelihood Estimation}

0 commit comments

Comments
 (0)