-
Notifications
You must be signed in to change notification settings - Fork 39
/
get_effect_variances.R
54 lines (44 loc) · 2.01 KB
/
get_effect_variances.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
get_effect_variances <-
function(data = data,
model = model,
which = all.vars(model[["terms"]])[-1], # which mes do we need variances of
type = c("response", "link", "terms"),
vcov = vcov(model),
vce = c("delta", "simulation", "bootstrap"),
iterations = 50L, # if vce == "bootstrap" or "simulation"
method = c("simple", "Richardson", "complex"), # passed to marginal_effects()
...) {
# march.arg() for arguments
type <- match.arg(type)
method <- match.arg(method)
vce <- match.arg(vce)
if (is.function(vcov)) {
vcov <- vcov(model)
}
if (vce == "delta") {
# default method
variances <- delta_once(data = data, model = model, type = type, vcov = vcov, method = method)
} else if (vce == "simulation") {
# copy model for quick use in estimation
tmpmodel <- model
tmpmodel$model <- NULL # remove data from model for memory
# simulate from multivariate normal
coefmat <- MASS::mvrnorm(iterations, coef(model), vcov)
# estimate AME from from each simulated coefficient vector
effectmat <- apply(coefmat, 1, function(coefrow) {
tmpmodel[["coefficients"]] <- coefrow
colMeans(marginal_effects(data, model = tmpmodel, type = type, method = method))
})
# calculate the variance of the simulated AMEs
variances <- apply(effectmat, 1, var, na.rm = TRUE)
} else if (vce == "bootstrap") {
# function to calculate AME for one bootstrap subsample
bootfun <- function() {
s <- sample(seq_len(nrow(data)), nrow(data), TRUE)
colMeans(marginal_effects(model = model, data = data[s,], type = type, method = method), na.rm = TRUE)
}
# bootstrap the data and take the variance of bootstrapped AMEs
variances <- apply(replicate(iterations, bootfun()), 1, var, na.rm = TRUE)
}
return(variances)
}