The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
The wnpmle package implements the weighted
nonparametric maximum likelihood estimator (wNPMLE) for the
marginal mean of recurrent events in the presence of a competing
terminal event.
Competing events are commonly modeled as independent
right-censorings, which leads to overestimation of the marginal mean of
a recurrent event. wnpmle provides valid estimation and
prediction via a weighted nonparametric maximum likelihood estimation
for two broad classes of semiparametric transformation models.
| Models | Link function G(x) | Special case at param = 1 |
|---|---|---|
Box-Cox transformation models (model = "boxcox") |
\(((1 + x)^\rho - 1)/\rho\) | Ghosh–Lin (\(\rho = 1\)) |
Logarithmic transformation models (model = "log") |
\(\log(1 + r x)/r\) | Proportional odds (\(r = 1\)) |
Both are estimated via automatic differentiation using TMB, which provides exact gradients and fast convergence.
Or from GitHub:
The package ships with a pre-processed version of the
bladder dataset from the survival package,
accessible via bladder_prep().
library(wnpmle)
bdata <- bladder_prep()
bdata_clean <- bdata[, c("id", "time", "status", "treat", "num", "size")]
head(bdata_clean)
#> id time status treat num size
#> 1 1 0 2 0 1 1
#> 2 2 1 2 0 1 3
#> 3 3 4 0 0 2 1
#> 4 4 7 0 0 1 1
#> 5 5 10 2 0 5 1
#> 6 6 6 1 0 4 1fit_bc <- wnpmle_fit(
Surv(time, status) ~ treat + num + size,
data = bdata_clean,
id = "id",
model = "boxcox",
rho = 1,
tau = 59,
se = "sandwich_adj"
)
#> Note: Using Makevars in C:\Users\abell\AppData\Local\Temp\Rtmp6Z8mOF\file61c45414c7f
#> using C++ compiler: 'G__~1.EXE (GCC) 13.3.0'
summary(fit_bc)
#>
#> Weighted NPMLE - Recurrent Events with Competing Terminal Event
#> Type : recurrent
#> Model : BOXCOX transformation ( rho = 1 )
#> Subjects : 86
#> Events : recurrent = 132 terminal = 22 censored = 64
#> Log-lik : -683.5759
#> Convergence: relative convergence (4)
#>
#> Coefficients:
#> Estimate SE z value Pr(>|z|)
#> treat -0.5363 0.2679 -2.002 0.045280
#> num 0.1727 0.0588 2.939 0.003298
#> size -0.0051 0.0681 -0.074 0.940900
#>
#> Cumulative baseline mean at time grid:
#> Lambda SE
#> A(tau/4) = 14.8 0.5111 0.1446
#> A(tau/2) = 29.5 1.1076 0.2903
#> A(tau) = 59 1.5882 0.4246
bl_bc <- baseline(fit_bc)
plot(bl_bc$time, bl_bc$Lambda, type = "s", lwd = 2,
xlab = "Time (months)", ylab = expression(hat(Lambda)(t)),
main = "Cumulative baseline mean (Ghosh-Lin)")
lines(bl_bc$time, bl_bc$lower, lty = 2, col = "grey50")
lines(bl_bc$time, bl_bc$upper, lty = 2, col = "grey50")fit_log <- wnpmle_fit(
Surv(time, status) ~ treat + num + size,
data = bdata_clean,
id = "id",
model = "log",
rho = 1,
tau = 59,
se = "sandwich_adj"
)
#> Note: Using Makevars in C:\Users\abell\AppData\Local\Temp\Rtmp6Z8mOF\file61c45414c7f
#> using C++ compiler: 'G__~1.EXE (GCC) 13.3.0'
summary(fit_log)
#>
#> Weighted NPMLE - Recurrent Events with Competing Terminal Event
#> Type : recurrent
#> Model : LOG transformation ( r = 1 )
#> Subjects : 86
#> Events : recurrent = 132 terminal = 22 censored = 64
#> Log-lik : -685.6581
#> Convergence: relative convergence (4)
#>
#> Coefficients:
#> Estimate SE z value Pr(>|z|)
#> treat -0.9916 0.4593 -2.159 0.030840
#> num 0.3540 0.1335 2.651 0.008017
#> size 0.0140 0.1424 0.098 0.921600
#>
#> Cumulative baseline mean at time grid:
#> Lambda SE
#> A(tau/4) = 14.8 0.5328 0.2972
#> A(tau/2) = 29.5 1.8252 1.0661
#> A(tau) = 59 3.8781 2.4199
bl_log <- baseline(fit_log)
plot(bl_log$time, bl_log$Lambda, type = "s", lwd = 2,
xlab = "Time (months)", ylab = expression(hat(Lambda)(t)),
main = "Cumulative baseline mean (proportional odds)")
lines(bl_log$time, bl_log$lower, lty = 2, col = "grey50")
lines(bl_log$time, bl_log$upper, lty = 2, col = "grey50")predict() evaluates the estimated marginal mean at new
covariate values. Here we compare the mean number of recurrences over
time for a treated vs. placebo patient, holding the number of initial
tumours and tumour size fixed at 1.
newdat <- data.frame(treat = c(0, 1), num = c(1, 1), size = c(1, 1))
pred <- predict(fit_bc, newdata = newdat,
times = seq(1, 50, by = 1))
plot(pred$time, pred$mu_1, type = "s", lwd = 2,
xlab = "Time (months)", ylab = "Marginal mean number of recurrences",
ylim = range(pred[, -1]))
lines(pred$time, pred$mu_2, lwd = 2, lty = 2, col = "firebrick")
legend("topleft", legend = c("Placebo", "Thiotepa"),
lty = c(1, 2), col = c("black", "firebrick"), bty = "n")plot_loglik() sweeps over a grid of parameter values and
plots the profile log-likelihood for both models on a single axis. The
logarithmic parameter r is shown on the left (negative axis) and the
Box-Cox parameter rho on the right (positive axis), meeting at zero
where the two models coincide.
The grids and the follow-up horizon tau are user-controlled. The
function fits length(rho_grid) + length(r_grid) models in
total, so computation time scales with grid size.
plot_loglik(
Surv(time, status) ~ treat + num + size,
data = bdata_clean,
id = "id",
tau = 59,
rho_grid = seq(0.01, 1.2, by = 0.01),
r_grid = seq(0.01, 1.2, by = 0.01)
)The filled circle marks rho = 1 (Ghosh-Lin) and the open circle marks r = 1 (proportional odds). The optimal parameter values are printed to the console.
The adjusted sandwich variance estimator accounts for the estimation
of the inverse probability of censoring weights. Set
se = "none" to skip SE computation, which is useful when
profiling over a grid of transformation parameters.
| Value | Description |
|---|---|
"sandwich_adj" |
Sandwich variance estimator (default) |
"sandwich" |
Sandwich variance estimator without adjustment (approximation) |
"fisher" |
Inverse fisher information |
"none" |
No standard errors, faster, useful for profiling |
| Method | Description |
|---|---|
print(fit) |
Compact coefficient table with z-values and p-values |
summary(fit) |
Adds cumulative baseline at tau/4, tau/2, tau |
coef(fit) |
Named coefficient vector |
vcov(fit) |
Full variance-covariance matrix for (beta, Lambda) |
logLik(fit) |
Log-likelihood (for use with AIC / BIC) |
AIC(fit) |
Akaike information criterion |
BIC(fit) |
Bayesian information criterion |
baseline(fit) |
Cumulative baseline mean data frame with CIs |
predict(fit, newdata) |
Marginal mean at new covariate values |
Bellach, A. and Kosorok, M.R. (2026). Weighted NPMLE for the marginal mean of recurrent events with a competing terminal event. arXiv preprint arXiv:2605.25934.
Bellach, A., Kosorok, M.R., Rüschendorf, L. and Fine, J.P. (2019). Weighted NPMLE for the subdistribution of a competing risk. Journal of the American Statistical Association, 114(525), 259–270. doi:10.1080/01621459.2017.1401540.
Ghosh, D. and Lin, D.Y. (2002). Marginal regression models for recurrent and terminal events. Statistica Sinica, 12, 663–688. doi:10.17615/pt0g-y207.
Zeng, D. and Lin, D.Y. (2006). Semiparametric transformation models with random effects for recurrent events. Biometrika, 93(3), 627–640. doi:10.1093/biomet/93.3.627.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.