Skip to content

Commit

Permalink
add in robincar vcov, its report and the tests (#16)
Browse files Browse the repository at this point in the history
* add in all draft functions

* [skip style] [skip vbump] Restyle files

* clean up design folder for merging

* Update branch 9 with main (#23)

* update data and fix design (#17)

* update data and fix design

* update treatment to factor

* fix styler and lint

* 7 counter factual prediction (#14)

* add function prototype

* add basic tests on functionality

* add readme

* add lm support

* update tests

* update prediction

* simplify

* fix typo

* fix check issues

* update vignettes skeleton

* use dummy data in test

* update print of cf predictions

* fix checks

* fix check issues

* update bias args

* [skip style] [skip vbump] Restyle files

* add treatment to counter factual prediction

* fix check

* 18 sandwich variance (#19)

* add vcov

* fix check issues

* correct issue

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* 20 add another developers design note (#22)

* add in all draft functions

* [skip style] [skip vbump] Restyle files

* clean up design folder for merging

* [skip style] [skip vbump] Restyle files

* Update .gitignore

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Liming <[email protected]>

---------

Co-authored-by: Liming <[email protected]>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* add robincar vcov calc functions and report function

* adding all the tests

* [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update

* [skip style] [skip vbump] Restyle files

* add Rds

* delete unneeded RdS

* add anhecova covariance (#24)

* add anhecova covariance

* fix error

* use new implementation of anhecova variance (#25)

* replace original function with faster version

* update anhecova variance and remove report functions

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Liming <[email protected]>
Co-authored-by: 27856297+dependabot-preview[bot]@users.noreply.github.com <27856297+dependabot-preview[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Jun 26, 2024
1 parent 0afe5fb commit 569d6ff
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ coverage.*
node_modules/
package-lock.json
package.json
RobinCar2.Rcheck/
RobinCar2*.tar.gz
RobinCar2*.tgz
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ S3method(print,prediction_cf)
S3method(vcovHC,prediction_cf)
export(bias)
export(predict_counterfactual)
export(vcovANHECOVA)
import(checkmate)
importFrom(sandwich,vcovHC)
importFrom(stats,coefficients)
Expand Down
81 changes: 81 additions & 0 deletions R/variance_anhecova.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#' ANHECOVA Covariance
#'
#' @param x (`prediction_cf`) Counter-factual prediction.
#' @param decompose (`flag`) whether to use decompose method to calculate the variance.
#' @param randomization (`string`) randomization method.
#' @param ... Not used.
#'
#' @return Named covariance matrix.
#' @export
vcovANHECOVA <- function(x, decompose = TRUE, randomization = "simple", ...) {
assert_class(x, "prediction_cf")
assert_flag(decompose)
assert_string(randomization)
resi <- attr(x, "residual")
est <- as.numeric(x)
preds <- attr(x, "predictions")
var_preds <- var(preds)
y <- attr(x, "response")
trt <- attr(x, "treatment")
pi_t <- as.numeric(table(trt) / length(trt))
trt_lvls <- levels(trt)
group_idx <- attr(x, "group_idx")

idx <- split(seq_len(length(trt)), trt)
cov_ymu <- vapply(idx, function(is) stats::cov(y[is], preds[is, ]), FUN.VALUE = rep(0, ncol(preds)))

if (decompose) {
vcov_sr <- (vapply(idx, function(is) stats::var(y[is]), FUN.VALUE = 0) + diag(var_preds) - 2 * diag(cov_ymu)) / pi_t
} else {
vcov_sr <- vapply(idx, function(is) stats::var(resi[is]), FUN.VALUE = 0) / pi_t
}

v <- diag(vcov_sr) + cov_ymu + t(cov_ymu) - var_preds
v <- v - h_get_erb(resi, group_idx, trt, pi_t, randomization)
ret <- v / length(resi)
dimnames(ret) <- list(trt_lvls, trt_lvls)
return(ret)
}

#' Obtain Adjustment for Proportion of Treatment Assignment
#' @keywords internal
#' @param pi (`numeric`) vector of proportions.
#' @return Numeric matrix.
h_adjust_pi <- function(pi) {
assert_numeric(pi)
diag(pi, nrow = length(pi)) - pi %*% t(pi)
}

#' Obtain Adjustment for Covariance Matrix
#' @param resi (`numeric`) vector of residuals.
#' @param group_idx (`list` of `integer`) index for each groups.
#' @param trt (`factor`) of treatment assignment.
#' @param pi (`numeric`) proportion of treatment assignment.
#' @param randomization (`string`) name of the randomization schema.
#' @keywords internal
h_get_erb <- function(resi, group_idx, trt, pi, randomization) {
assert_list(group_idx, types = "integer")
if (length(group_idx) == 1L) {
return(0)
}
assert_string(randomization)
if (randomization %in% c("simple", "pocock-simon")) {
return(0)
}
assert_numeric(resi)
assert_factor(trt)
assert_numeric(pi)

omegaz_sr <- h_adjust_pi(pi)
n_tot <- length(resi)
resi_per_strata <- vapply(
group_idx,
function(ii) {
v <- vapply(split(resi[ii], trt[ii]), mean, FUN.VALUE = 0)
v * sqrt(length(ii) / n_tot)
},
FUN.VALUE = rep(0, length(levels(trt)))
)
rb_z <- resi_per_strata / as.numeric(pi)
tcrossprod(rb_z) * omegaz_sr
}
6 changes: 4 additions & 2 deletions R/variance.R → R/variance_hc.R
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#### Main functions ####

#' @exportS3Method
vcovHC.prediction_cf <- function(x, type = "HC3",...) {
vcovHC.prediction_cf <- function(x, type = "HC3", ...) {
fit <- attr(x, "fit")
vc <- vcovHC(fit, type = type)
mm <- attr(x, "model_matrix")
n <- length(md) / length(names(x))
n <- nrow(mm) / length(names(x))
md <- family(fit)$mu.eta(attr(x, "predictions_linear")) / n
z <- block_sum(as.vector(md) * mm, n)
ret <- z %*% vc %*% t(z)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ d <- sim_data(500)
fit <- glm(y ~ trt:z1 + trt, family = binomial(link = "logit"), data = d)

## start of the pkg
source(file.path(getwd(), "design", "package_structure", "all_draft_functions.R"))
pred_counterfact <- get_countfact_pred(fit, "trt")
fit.fvcov <- calculate_f_vcov(fit, "trt", pred_counterfact)
report_fvcov(fit.fvcov, 3)
18 changes: 18 additions & 0 deletions man/h_adjust_pi.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions man/h_get_erb.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions man/vcovANHECOVA.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions tests/testthat/_snaps/variance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# vcovHC works

Code
vcovHC(pc)
Output
pbo trt1 trt2
pbo 1.106024e-03 4.523445e-07 -9.709004e-06
trt1 4.523445e-07 1.164889e-03 -7.709031e-07
trt2 -9.709004e-06 -7.709031e-07 1.170214e-03

# vcovANHECOVA works

Code
vcovANHECOVA(pc)
Output
pbo trt1 trt2
pbo 1.128902e-03 1.856234e-05 1.333885e-05
trt1 1.856234e-05 1.184599e-03 2.178112e-05
trt2 1.333885e-05 2.178112e-05 1.157268e-03

---

Code
vcovANHECOVA(pc, randomization = "permute_block")
Output
pbo trt1 trt2
pbo 1.128902e-03 1.856234e-05 1.333885e-05
trt1 1.856234e-05 1.184599e-03 2.178112e-05
trt2 1.333885e-05 2.178112e-05 1.157268e-03

16 changes: 16 additions & 0 deletions tests/testthat/test-variance.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
test_that("vcovHC works", {
pc <- predict_counterfactual(fit_binom, treatment ~ s1)
expect_snapshot(
vcovHC(pc)
)
})

test_that("vcovANHECOVA works", {
pc <- predict_counterfactual(fit_binom, treatment ~ s1)
expect_snapshot(
vcovANHECOVA(pc)
)
expect_snapshot(
vcovANHECOVA(pc, randomization = "permute_block")
)
})

0 comments on commit 569d6ff

Please sign in to comment.