diff --git a/DESCRIPTION b/DESCRIPTION index 8574f89..963cc9a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: targeted Type: Package Title: Targeted Inference -Version: 0.5 -Date: 2024-02-22 +Version: 0.6 +Date: 2024-04-15 Authors@R: c(person(given = "Klaus K.", family = "Holst", role = c("aut", "cre"), @@ -23,7 +23,7 @@ Description: Various methods for targeted and semiparametric inference including linear model parameters (Vansteelandt et al. (2022) ). Depends: R (>= 4.0), - lava (>= 1.7.0) + lava (>= 1.8.0) Imports: data.table, digest, diff --git a/NAMESPACE b/NAMESPACE index 2c56a9e..4626241 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,6 +6,7 @@ S3method(coef,targeted) S3method(estimate,ml_model) S3method(logLik,targeted) S3method(model.matrix,design) +S3method(offsets,design) S3method(plot,calibration) S3method(predict,NB) S3method(predict,NB2) @@ -20,6 +21,7 @@ S3method(print,summary.ate.targeted) S3method(print,summary.riskreg.targeted) S3method(print,summary.targeted) S3method(print,targeted) +S3method(specials,design) S3method(summary,ate.targeted) S3method(summary,cross_validated) S3method(summary,design) @@ -27,6 +29,7 @@ S3method(summary,riskreg.targeted) S3method(summary,targeted) S3method(update,design) S3method(vcov,targeted) +S3method(weights,design) export(ML) export(NB) export(NB2) @@ -47,6 +50,7 @@ export(expand.list) export(isoregw) export(ml_model) export(nondom) +export(offsets) export(pava) export(riskreg) export(riskreg_cens) @@ -55,6 +59,7 @@ export(riskreg_mle) export(scoring) export(softmax) export(solve_ode) +export(specials) export(specify_ode) import(Rcpp) import(methods) diff --git a/R/RATE.R b/R/RATE.R index 48a378c..bbc8c80 100644 --- a/R/RATE.R +++ b/R/RATE.R @@ -190,7 +190,7 @@ RATE.surv <- function(response, post.treatment, treatment, censoring, attr(surv.response, "type") == "right", # only allows right censoring attr(surv.censoring, "type") == "right", # only allows right censoring all(surv.response[,1] == surv.censoring[ ,1]), # time must be equal - all(order(surv.response[,1]) == (1:nrow(data))) # data must be ordered by time and have no missing values + all(order(surv.response[,1]) == (seq_len(nrow(data)))) # data must be ordered by time and have no missing values ) rm(surv.response, surv.censoring) diff --git a/R/cate.R b/R/cate.R index 39b0625..f0f8907 100644 --- a/R/cate.R +++ b/R/cate.R @@ -31,8 +31,8 @@ ate_if_fold <- function(fold, data, cate_fold1 <- function(fold, data, score, treatment_des) { y <- score[fold] - x <- update(treatment_des, data[fold, , drop=FALSE])$x - lm.fit(y=y, x=x)$coef + x <- update(treatment_des, data[fold, , drop = FALSE])$x + lm.fit(y = y, x = x)$coef } ##' Conditional Average Treatment Effect estimation via Double Machine Learning @@ -225,14 +225,14 @@ cate <- function(treatment, } score_fold <- function(fold, - data, - propensity_model, - response_model, - importance_model, - treatment, level) { - dtrain <- data[-fold,] - deval <- data[fold,] - + data, + propensity_model, + response_model, + importance_model, + treatment, level) { + dtrain <- data[-fold, ] + deval <- data[fold, ] + # training tmp <- propensity_model$estimate(dtrain) tmp <- response_model$estimate(dtrain) @@ -240,25 +240,27 @@ score_fold <- function(fold, Y <- response_model$response(dtrain) X <- dtrain X[, treatment] <- level - pr <- propensity_model$predict(newdata=dtrain) - if (NCOL(pr)>1) - pr <- pr[,2] - eY <- response_model$predict(newdata=X) - D <- A/pr*(Y-eY) + eY + pr <- propensity_model$predict(newdata = dtrain) + if (NCOL(pr) > 1) { + pr <- pr[, 2] + } + eY <- response_model$predict(newdata = X) + D <- A / pr * (Y - eY) + eY X[["D_"]] <- D tmp <- importance_model$estimate(data = X) - # evaluation + # evaluation A <- propensity_model$response(deval) Y <- response_model$response(deval) X <- deval X[, treatment] <- level - pr <- propensity_model$predict(newdata=deval) - if (NCOL(pr)>1) - pr <- pr[,2] - eY <- response_model$predict(newdata=X) - D <- A/pr*(Y-eY) + eY - II <- importance_model$predict(newdata=X) + pr <- propensity_model$predict(newdata = deval) + if (NCOL(pr) > 1) { + pr <- pr[, 2] + } + eY <- response_model$predict(newdata = X) + D <- A / pr * (Y - eY) + eY + II <- importance_model$predict(newdata = X) return(list(II = II, D = D)) } @@ -315,7 +317,7 @@ crr <- function(treatment, data, nfolds=5, type="dml1", - ...){ + ...) { cl <- match.call() if (is.character(treatment)) { treatment <- as.formula(paste0(treatment, "~", 1)) @@ -326,7 +328,7 @@ crr <- function(treatment, } if (length(contrast)!=2) stop("Expected contrast vector of length 2.") - + response_var <- lava::getoutcome(response_model$formula, data=data) treatment_var <- lava::getoutcome(treatment) treatment_f <- function(treatment_level, x=paste0(".-", response_var)) @@ -338,18 +340,18 @@ crr <- function(treatment, importance_formula <- update(treatment, D_~.) importance_model <- SL(importance_formula, ...) } - + n <- nrow(data) folds <- split(sample(1:n, n), rep(1:nfolds, length.out = n)) folds <- lapply(folds, sort) - + ff <- Reduce(c, folds) idx <- order(ff) - + # D_a = I(A=a)/P(A=a|W)[Y - E[Y|A=a, W]] + E[Y|A=a, W], a = {1,0} D <- list() # II = E[E[Y|A=a, W]|V] = E[D_a|V], a = {1,0} - II <- list() + II <- list() pb <- progressr::progressor(steps = length(contrast)*nfolds) for (i in seq_along(contrast)) { a <- contrast[i] @@ -373,11 +375,11 @@ crr <- function(treatment, } names(D) <- contrast names(II) <- contrast - + score <- D[[1]]*II[[2]] - D[[2]]*II[[1]] score <- score + II[[1]] * II[[2]] score <- score * II[[2]]^(-2) - + if (type=="dml1") { est1 <- lapply(folds, function(x) cate_fold1(x, data = data, @@ -388,14 +390,13 @@ crr <- function(treatment, est <- coef(lm(score ~ -1+desA$x)) } names(est) <- names(desA$x) - + M1 <- desA$x C <- -n^(-1) * crossprod(M1) IF <- -solve(C) %*% t(M1 * as.vector(score - M1 %*% est)) IF <- t(IF) - + estimate <- estimate(coef=est, IC=IF) - res <- list(folds=folds, score=score, treatment_des=desA, diff --git a/R/design.R b/R/design.R index 39664cf..e5351d0 100644 --- a/R/design.R +++ b/R/design.R @@ -10,15 +10,18 @@ ##' @author Klaus Kähler Holst ##' @export design <- function(formula, data, intercept=FALSE, - rm_envir=FALSE, ...) { - tt <- terms(formula, data=data) + rm_envir=FALSE, ..., specials = c("weights", "offset")) { + tt <- terms(formula, data = data) if (!intercept) attr(tt, "intercept") <- 0 mf <- model.frame(tt, data=data, ...) x_levels <- .getXlevels(tt, mf) x <- model.matrix(mf, data=data) y <- model.response(mf, type="any") - specials <- names(substitute(list(...)))[-1] + specials <- union( + specials, + names(substitute(list(...)))[-1] + ) specials_list <- c() if (length(specials)>0) { for (s in specials) { @@ -38,19 +41,23 @@ design <- function(formula, data, intercept=FALSE, } ##' @export -update.design <- function(object, data=NULL, ...) { +update.design <- function(object, data = NULL, ..., + specials = c("weights", "offset")) { if (is.null(data)) data <- object$data - mf <- with(object, model.frame(terms, data=data, ..., - xlev = xlevels, - drop.unused.levels=FALSE)) + mf <- model.frame(object$terms, data=data, ..., + xlev = object$xlevels, + drop.unused.levels=FALSE) x <- model.matrix(mf, data=data, ..., xlev = object$xlevels) object[["y"]] <- NULL for (s in object$specials) { object[[s]] <- NULL } - specials <- names(substitute(list(...)))[-1] + specials2 <- names(substitute(list(...)))[-1] + for (s in specials2) { + object[[s]] <- eval(substitute(model.extract(mf, s), list(s = s))) + } for (s in specials) { - object[[s]] <- eval(substitute(model.extract(mf, s), list(s=s))) + object[[s]] <- do.call(model.extract, list(mf, s)) } object$specials <- specials object$x <- x @@ -61,12 +68,34 @@ update.design <- function(object, data=NULL, ...) { model.matrix.design <- function(object, drop.intercept = FALSE, ...) { if (drop.intercept) { intercept <- which(attr(object$x, "assign") == 0) - if (length(intercept)>0) - return(object$x[, -intercept, drop=FALSE]) + if (length(intercept) > 0) { + return(object$x[, -intercept, drop = FALSE]) + } } return(object$x) } +##' @export +weights.design <- function(object, ...) { + specials(object, "weights") +} + +##' @export +offsets <- function(object, ...) UseMethod("offsets") + +##' @export +offsets.design <- function(object, ...) { + specials(object, "offset") +} + +##' @export +specials <- function(object, ...) UseMethod("specials") + +##' @export +specials.design <- function(object, which, ...) { + return(object[[which]]) +} + ##' @export summary.design <- function(object, ...) { object$x <- object$x[0, ] diff --git a/R/ml_model.R b/R/ml_model.R index a7b7382..519ede3 100644 --- a/R/ml_model.R +++ b/R/ml_model.R @@ -58,7 +58,8 @@ ml_model <- R6::R6Class("ml_model", estimate, predict=stats::predict, predict.args=NULL, - info=NULL, specials, + info=NULL, + specials = c(), response.arg="y", x.arg="x", ...) { @@ -72,7 +73,8 @@ ml_model <- R6::R6Class("ml_model", if (!("..." %in% formalArgs(estimate))) { formals(estimate) <- c(formals(estimate), alist(... = )) } - des.args <- lapply(substitute(specials), function(x) x)[-1] + ## des.args <- lapply(substitute(specials), function(x) x)[-1] + des.args <- list(specials = specials) fit_formula <- "formula"%in%formalArgs(estimate) fit_response_arg <- response.arg %in% formalArgs(estimate) fit_x_arg <- x.arg%in%formalArgs(estimate) @@ -82,7 +84,6 @@ ml_model <- R6::R6Class("ml_model", ## if (!fit_x_arg && !("data"%in%formalArgs(estimate))) ## stop("Estimation method must have an argument 'x' or 'data'") - self$args <- dots no_formula <- is.null(formula) if (no_formula) { @@ -128,10 +129,16 @@ ml_model <- R6::R6Class("ml_model", } private$predfun <- function(object, data, ...) { if (fit_formula || no_formula) { - args <- c(list(object, newdata=data), predict.args, list(...)) + args <- c(list(object, newdata = data), predict.args, list(...)) } else { - x <- model.matrix(update(attr(object, "design"), data)) - args <- c(list(object, newdata=x), predict.args, list(...)) + args <- list(...) + des <- update(attr(object, "design"), data) + for (s in des$specials) { + if (is.null(args[[s]])) args[[s]] <- des[[s]] + } + args <- c(list(object, + newdata = model.matrix(des) + ), predict.args, args) } return(do.call(private$init.predict, args)) } @@ -154,7 +161,7 @@ ml_model <- R6::R6Class("ml_model", estimate = function(data, ..., store=TRUE) { res <- private$fitfun(data, ...) if (store) private$fitted <- res - invisible(res) + return(invisible(res)) }, ##' @description @@ -292,7 +299,7 @@ predict.ml_model <- function(object, ...) { ##' @param ... additional arguments to model object ##' @details ##' model 'sl' (SuperLearner::SuperLearner) -##' args: SL.library, cvControl, f=u,X_i)S^c(u|X_i)}^{-1} d M_i^c, -## h = E(Q|T>u=u,X), function(data, u, S, S.tau, tau) -binreg_augmentation <- function(T.est, C.est, data, time, event, tau, h, phreg=TRUE, - sample=0, blocksize=0, ...) { +## vector of size n with values \int_0^tau E(Q_u|T_i>=u,X_i)S^c(u|X_i)}^{-1} d +## M_i^c, h = E(Q|T>u=u,X), function(data, u, S, S.tau, tau) +binreg_augmentation <- function(T.est, + C.est, + data, + time, + event, + tau, + h, + phreg=TRUE, + sample=0, + blocksize=0, + ...) { n <- nrow(data) - data.C <- data[event == 0,] + data.C <- data[event == 0, , drop = FALSE] time.C <- time[event == 0] - delta <- event; delta[time>tau] <-1 + delta <- event + delta[time > tau] <- 1 - S <- cumhaz(T.est, newdata = data.C, times = time.C, individual.time=TRUE)$surv - S.tau <- cumhaz(T.est, newdata = data.C, times = tau)$surv[1,] - Sc <- cumhaz(C.est, newdata = data.C, times = time.C, individual.time=TRUE)$surv + S <- cumhaz(T.est, + newdata = data.C, + times = time.C, + individual.time = TRUE + )$surv + S.tau <- cumhaz(T.est, + newdata = data.C, + times = tau + )$surv[1, ] + Sc <- cumhaz(C.est, + newdata = data.C, + times = time.C, + individual.time = TRUE + )$surv stopifnot(all(S * Sc> 0)) ## Counting process term Nc <- vector(mode = "numeric", length = n) @@ -301,8 +332,8 @@ binreg_augmentation <- function(T.est, C.est, data, time, event, tau, h, phreg=T i <- i+1 at.risk <- tt<=time[i] ## E[Q|T>=u, X] - Eq = h(data[r,], tt, S[,i], S.tau[,i], tau) / Sc$surv[,i] - lc <- sum((Eq * at.risk * Sc$dchf[,i]) [tt<=tau]) + Eq <- h(data[r, ], tt, S[, i], S.tau[, i], tau) / Sc$surv[, i] + lc <- sum((Eq * at.risk * Sc$dchf[, i]) [tt<=tau]) Lc[r] <- lc } } diff --git a/R/utils.R b/R/utils.R index bd08775..7a06b06 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,25 +1,31 @@ -Identical <- function(x, y=1, tolerance=.Machine$double.eps^0.5) { - Mod(x-y) < tolerance +Identical <- function(x, y = 1, tolerance = .Machine$double.eps^0.5) { + Mod(x - y) < tolerance } rd2pr <- function(rd, op) { - a <- op - 1 - b <- -op*(2-rd) - rd - p0 <- (-b - sqrt(b^2 - 4*op*(1-rd)*a))/(2*a) - op1 <- which(sapply(op, function(x) Identical(x, 1))) - if (length(op1) > 0) - p0[op1] = 0.5 * (1 - rd[op1]) - p1 <- p0 + rd - cbind(p0, p1) + a <- op - 1 + b <- -op * (2 - rd) - rd + p0 <- (-b - sqrt(b^2 - 4 * op * (1 - rd) * a)) / (2 * a) + op1 <- lapply(op, function(x) Identical(x, 1)) |> + unlist() |> + which() + if (length(op1) > 0) { + p0[op1] <- 0.5 * (1 - rd[op1]) + } + p1 <- p0 + rd + cbind(p0, p1) } rr2pr <- function(rr, op) { - b <- op*(1 + rr) - a <- rr*(1 - op) - p0 <- (-b + sqrt(b^2 + 4*a*op))/(2*a) - op1 <- which(sapply(op, function(x) Identical(x, 1))) - if (length(op1) > 0) - p0[op1] = 1/(1+rr[op1]) - p1 <- p0*rr - cbind(p0, p1) + b <- op * (1 + rr) + a <- rr * (1 - op) + p0 <- (-b + sqrt(b^2 + 4 * a * op)) / (2 * a) + op1 <- lapply(op, function(x) Identical(x, 1)) |> + unlist() |> + which() + if (length(op1) > 0) { + p0[op1] <- 1 / (1 + rr[op1]) + } + p1 <- p0 * rr + cbind(p0, p1) } diff --git a/inst/misc/dp.R b/inst/misc/dp.R index 0ac5839..d0758e4 100644 --- a/inst/misc/dp.R +++ b/inst/misc/dp.R @@ -62,7 +62,7 @@ dormand_prince <- function(f, y0, t1, t0=0, h0=0.1, } step <- function(t, h, y, fac_max) { - accept <- FALSE; + accept <- FALSE teval <- t+h while (!accept) { teval <- t+h diff --git a/inst/misc/proto.R b/inst/misc/proto.R index cba7913..3f8c40c 100644 --- a/inst/misc/proto.R +++ b/inst/misc/proto.R @@ -5,8 +5,8 @@ targetMLE_proto <- function(y,x,x1,x2=x1,weights=rep(1,length(y)),type="rd") { beta <- rep(0,ncol(x2)) theta <- c(alpha,beta) pa <- function(theta) { - alpha <- theta[seq(ncol(x1))] - beta <- theta[seq(ncol(x2))+ncol(x1)] + alpha <- theta[seq_len(ncol(x1))] + beta <- theta[seq_len(ncol(x2)) + ncol(x1)] op <- exp(x2%*%beta) if (type=="rd") { target <- tanh(x1%*%alpha) @@ -29,33 +29,33 @@ targetMLE_proto <- function(y,x,x1,x2=x1,weights=rep(1,length(y)),type="rd") { target <- pp[,4] op <- pp[,5] p <- pp[,1] - if (type=="rd") { + if (type=="rd") { s0 <- p0 * (1 - p0) s1 <- p1 * (1 - p1) dp0.rd <- -s0/(s0 + s1) dp0.rd <- (dp0.rd + x)*(1 - target^2) - d.alpha = apply(x1,2, function(x) x*dp0.rd ) - dp0.op = s0 * s1/(s0 + s1) - d.beta <- apply(x2,2, function(x) x*dp0.op ) + d.alpha <- apply(x1, 2, function(x) x*dp0.rd) + dp0.op <- s0 * s1/(s0 + s1) + d.beta <- apply(x2, 2, function(x) x*dp0.op) } else { s <- (1-p0) + (1-p1) - tmp <- 1 - x + x*target; + tmp <- 1 - x + x*target dp.rr <- -p0/p1 * p0*(1-p0) / s * tmp + x*p0 dp.rr <- dp.rr*target d.alpha <- apply(x1,2, function(x) x*dp.rr) - s <- (1-p1)*p1 + (1-p0)*p1 - dp.op <- (1-p0)^2*(1-p1)^2 / s * tmp * op; - d.beta <- apply(x2,2, function(x) x*dp.op) + s <- (1-p1)*p1 + (1-p0)*p1 + dp.op <- (1-p0)^2*(1-p1)^2 / s * tmp * op + d.beta <- apply(x2,2, function(x) x*dp.op) } S <- (y-p)/(p*(1-p)) - val <- apply(cbind(d.alpha,d.beta),2,function(x) weights*x*S) + val <- apply(cbind(d.alpha,d.beta), 2, function(x) weights*x*S) return(colSums(val)) } d2logl <- function(theta) deriv(dlogl,theta) op <- nlminb(theta, function(p) -logl(p), function(p) -dlogl(p)) V <- -Inverse(d2logl(op$par)) - est <- estimate(coef=op$par,vcov=V) - list(estimate=est,opt=op, coef=op$par) + est <- estimate(coef=op$par, vcov=V) + list(estimate=est, opt=op, coef=op$par) } @@ -63,7 +63,7 @@ Us <- function(alpha, theta, y, x, x1, x2=x1, x3=x2, weights=rep(1, length(y)), - optimal=TRUE, type="rd", indiv=TRUE, ...) { + optimal=TRUE, type="rd", indiv=TRUE, ...) { x1 <- cbind(x1) x2 <- cbind(x2) x3 <- cbind(x3) @@ -88,10 +88,10 @@ Us <- function(alpha, theta, denom <- (1-pr)/(p0*(1-p0)) + pr/(p1*(1-p1)) omega <- nom/denom / ( pr*p0*(1-p0) ) } else { - nom <- pr*p1/(1-p1) + nom <- pr*p1/(1-p1) # E(A pa/(1-Pa) |V) = pr*drho/[p1(1-p1)] denom <- (1-pr)*p0/(1-p0) + pr*p1/(1-p1) - omega <- nom/denom / ( pr*(1-p0) ) + omega <- nom/denom / ( pr*(1-p0) ) } } if (type=="rd") { @@ -110,7 +110,9 @@ Us <- function(alpha, theta, colSums(res) } -target_proto <- function(y,x,x1,x2=x1,x3=x2,weights=rep(1,length(y)),optimal=TRUE,std.err=FALSE,type="rd",...) { +target_proto <- function(y, x, x1, x2=x1, x3=x2, + weights=rep(1, length(y)), + optimal=TRUE, std.err=FALSE, type="rd", ...) { x1 <- cbind(x1) x2 <- cbind(x2) x3 <- cbind(x3) @@ -139,7 +141,9 @@ target_proto <- function(y,x,x1,x2=x1,x3=x2,weights=rep(1,length(y)),optimal=TRU pp <- pa(theta0) print(theta0) print(head(pp)) - p0 <- pp[,2]; p1 <- pp[,3]; target <- pp[,4] + p0 <- pp[, 2] + p1 <- pp[, 3] + target <- pp[, 4] if (type=="rd") { ## omega.opt = (1 - rd) * (1 + rd)/(p0 * (1 - p0) + rd * (1 - pr) * ## (1 - 2 * p0 - rd)) @@ -177,18 +181,28 @@ target_proto <- function(y,x,x1,x2=x1,x3=x2,weights=rep(1,length(y)),optimal=TRU u <- function(p) as.vector(colSums(U(p))) opt <- nlminb(alpha0,function(x) sum(u(x)^2),...) if (std.err) { - thetahat <- c(theta0,gamma); + thetahat <- c(theta0,gamma) alphahat <- opt$par alpha.index <- seq_along(opt$par) theta.index <- seq_along(theta0) + length(alpha.index) - gamma.index <- seq_along(gamma) + length(alpha.index) + length(theta.index) + gamma.index <- seq_along(gamma) + length(alpha.index) + + length(theta.index) pp <- c(alphahat, thetahat) - UU <- function(p,indiv=FALSE) Us(alpha=p[seq_along(alphahat)], theta=p[seq_along(thetahat)+length(alphahat)], y=y, x=x, x1=x1,x2=x2,x3=x3,weights=weights,optimal=optimal, indiv=indiv) + UU <- function(p, indiv = FALSE) { + Us( + alpha = p[seq_along(alphahat)], + theta = p[seq_along(thetahat) + length(alphahat)], + y = y, x = x, x1 = x1, x2 = x2, x3 = x3, + weights = weights, optimal = optimal, indiv = indiv + ) + } DU <- deriv(UU,pp) U0 <- UU(pp,indiv=TRUE) iid.gamma <- iid(propmod) iid.theta <- iid(mle$estimate) - ii <- (U0 - iid.theta%*%t(DU[,theta.index]) - iid.gamma%*%t(DU[,gamma.index])) %*% t(solve(DU[,alpha.index])) + ii <- (U0 - iid.theta %*% t(DU[, theta.index]) - + iid.gamma %*% t(DU[, gamma.index])) %*% + t(solve(DU[, alpha.index])) V <- crossprod(ii) } else { V <- ii <- NULL diff --git a/man/ML.Rd b/man/ML.Rd index 6f86a57..4116de3 100644 --- a/man/ML.Rd +++ b/man/ML.Rd @@ -18,7 +18,7 @@ Wrapper for ml_model } \details{ model 'sl' (SuperLearner::SuperLearner) -args: SL.library, cvControl, fmin(T,tau)). This can be decomposed into an integral wrt the counting process, \eqn{dN_c(t)} and the compensator \eqn{d\Lambda_c(t)} where the latter term can be computational intensive to calculate. Rather than calculating this integral in all observed time points, we can make a -coarser evaluation which can be controlled by setting \code{control=(sample=N)}. -With \code{N=0} the (computational intensive) standard evaluation is used.##' +coarser evaluation which can be controlled by setting +\code{control=(sample=N)}. With \code{N=0} the (computational intensive) +standard evaluation is used.##' } \author{ Klaus K. Holst, Andreas Nordland diff --git a/man/targeted-package.Rd b/man/targeted-package.Rd index 02c4be5..7cdca5d 100644 --- a/man/targeted-package.Rd +++ b/man/targeted-package.Rd @@ -21,6 +21,7 @@ example(calibration) \seealso{ Useful links: \itemize{ + \item \url{https://kkholst.github.io/targeted/} \item Report bugs at \url{https://github.com/kkholst/targeted/issues} } diff --git a/vignettes/ode.Rmd b/vignettes/ode.Rmd index 4a5f222..cc7d6a6 100644 --- a/vignettes/ode.Rmd +++ b/vignettes/ode.Rmd @@ -129,11 +129,11 @@ scatterplot3d::scatterplot3d(y, cex.symbols=0.1, type='b', ``` To illustrate the use of exogenous inputs, consider the following simulated data - ```{r} n <- 1e4 tt <- seq(0, 10, length.out=n) # Time -xx <- rep(0, n); xx[(n/3):(2*n/3)] <- 1 # Exogenous input, x(t) +xx <- rep(0, n) +xx[(n / 3):(2 * n / 3)] <- 1 # Exogenous input, x(t) input <- cbind(tt, xx) ```