diff --git a/DESCRIPTION b/DESCRIPTION index aae7e71..e450e50 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -27,4 +27,4 @@ Encoding: UTF-8 Language: en-US LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 diff --git a/NAMESPACE b/NAMESPACE index 5db533a..c48614f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,6 +8,12 @@ S3method(treatment_effect,lm) S3method(treatment_effect,prediction_cf) S3method(vcovHC,prediction_cf) export(bias) +export(h_diff) +export(h_jac_diff) +export(h_jac_odds_ratio) +export(h_jac_ratio) +export(h_odds_ratio) +export(h_ratio) export(predict_counterfactual) export(treatment_effect) export(vcovANHECOVA) diff --git a/R/treatment_effect.R b/R/treatment_effect.R index 46c1242..06060f3 100644 --- a/R/treatment_effect.R +++ b/R/treatment_effect.R @@ -91,48 +91,77 @@ odds_ratio <- function(object, ...) { treatment_effect(object, eff_measure = h_odds_ratio, eff_jacobian = h_jac_odds_ratio, ...) } +#' Contrast Functions and Jacobians +#' @rdname contrast +#' @param x (`numeric`) Vector of values. +#' @return Vector of contrasts, or matrix of jacobians. +#' @examples +#' h_diff(1:3) +#' h_jac_ratio(1:3) +#' @export h_diff <- function(x) { assert_numeric(x) d <- outer(x, x, `-`) d[lower.tri(d)] } + +#' @rdname contrast +#' @export h_jac_diff <- function(x) { assert_numeric(x) n <- length(x) - if (n == 2) { - matrix(c(-1, 1), nrow = 1L) - } else { - jacobian(h_diff, x) - } + l <- h_lower_tri_idx(n) + ret <- matrix(0, nrow = nrow(l), ncol = n) + ret[cbind(seq_len(nrow(ret)), l[, 1])] <- 1 + ret[cbind(seq_len(nrow(ret)), l[, 2])] <- -1 + ret } +#' @rdname contrast +#' @export h_ratio <- function(x) { assert_numeric(x, lower = 0) d <- outer(x, x, `/`) d[lower.tri(d)] } + +#' @rdname contrast +#' @export h_jac_ratio <- function(x) { assert_numeric(x, lower = 0) n <- length(x) - if (n == 2) { - matrix(c(-x[2] / x[1]^2, 1 / x[1]), nrow = 1L) - } else { - jacobian(h_ratio, x) - } + l <- h_lower_tri_idx(n) + ret <- matrix(0, nrow = nrow(l), ncol = n) + ret[cbind(seq_len(nrow(ret)), l[, 1])] <- 1 / x[l[, 2]] + ret[cbind(seq_len(nrow(ret)), l[, 2])] <- -x[l[, 1]] / x[l[, 2]]^2 + ret } +#' @rdname contrast +#' @export h_odds_ratio <- function(x) { assert_numeric(x, lower = 0, upper = 1) y <- x / (1 - x) h_ratio(y) } +#' @rdname contrast +#' @export h_jac_odds_ratio <- function(x) { - assert_numeric(x, lower = 0, upper = 1) + assert_numeric(x, lower = 0) n <- length(x) - if (n == 2) { - matrix(c(-x[2] / ((1 - x[2]) * x[1]^2), (1 - x[1]) / ((1 - x[2])^2 * x[1])), nrow = 1L) - } else { - jacobian(h_odds_ratio, x) - } + l <- h_lower_tri_idx(n) + ret <- matrix(0, nrow = nrow(l), ncol = n) + ret[cbind(seq_len(nrow(ret)), l[, 1])] <- (1 - x[l[, 2]]) / ((1 - x[l[, 1]])^2 * x[l[, 2]]) + ret[cbind(seq_len(nrow(ret)), l[, 2])] <- -x[l[, 1]] / ((1 - x[l[, 1]]) * x[l[, 2]]^2) + ret +} + +#' Lower Triangular Index +#' @param n (`int`) Number of rows/columns. +#' @return Matrix of lower triangular indices. +#' @keywords internal +h_lower_tri_idx <- function(n) { + rc <- c(n, n) + which(.row(rc) > .col(rc), arr.ind = TRUE) } diff --git a/man/contrast.Rd b/man/contrast.Rd new file mode 100644 index 0000000..ae36391 --- /dev/null +++ b/man/contrast.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/treatment_effect.R +\name{h_diff} +\alias{h_diff} +\alias{h_jac_diff} +\alias{h_ratio} +\alias{h_jac_ratio} +\alias{h_odds_ratio} +\alias{h_jac_odds_ratio} +\title{Contrast Functions and Jacobians} +\usage{ +h_diff(x) + +h_jac_diff(x) + +h_ratio(x) + +h_jac_ratio(x) + +h_odds_ratio(x) + +h_jac_odds_ratio(x) +} +\arguments{ +\item{x}{(\code{numeric}) Vector of values.} +} +\value{ +Vector of contrasts, or matrix of jacobians. +} +\description{ +Contrast Functions and Jacobians +} +\examples{ +h_diff(1:3) +h_jac_ratio(1:3) +} diff --git a/man/h_lower_tri_idx.Rd b/man/h_lower_tri_idx.Rd new file mode 100644 index 0000000..9fcd3be --- /dev/null +++ b/man/h_lower_tri_idx.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/treatment_effect.R +\name{h_lower_tri_idx} +\alias{h_lower_tri_idx} +\title{Lower Triangular Index} +\usage{ +h_lower_tri_idx(n) +} +\arguments{ +\item{n}{(\code{int}) Number of rows/columns.} +} +\value{ +Matrix of lower triangular indices. +} +\description{ +Lower Triangular Index +} +\keyword{internal}