HTE {FactorHet}R Documentation

Estimate heterogeneous treatment effects by individual or moderator

Description

These functions estimate heterogeneous effects from FactorHet at the individual level or by the average value of a moderator. They can be used to produce individual-level estimates that can be compared against other methods for estimating heterogeneous effects.

Usage

HTE_by_individual(object, AME, design = NULL)

HTE_by_moderator(
  object,
  AME,
  moderators = NULL,
  design = NULL,
  points_continuous = 10,
  overall_AME = FALSE,
  verbose = FALSE
)

Arguments

object

An object from FactorHet, FactorHet_mbo.

AME

An estimate of the average marginal effects by group from AME.

design

An optional data.frame of moderator values on which to produce the individual-level or average conditional average marginal effects. Note: There should be one row per observation if this function is used. The default is NULL which uses the estimation data.

moderators

An argument that contains a list of moderators to evaluate. The default is NULL and considers all moderators.

points_continuous

A positive integer value that indicates the number of equally spaced points to evaluate a continuous moderator over.

overall_AME

A logical value that indicates whether to compute the AME over the entire design without modification. The default is FALSE.

verbose

A logical value that indicates whether progress should be reported. The default is FALSE.

Details

The functions here allow for, first, estimation of conditional average marginal effects for each individual given their pre-treatment moderators (HTE_by_individual). This is a weighted average of the AME for each group by the individual's group membership probabilities, i.e. \hat{\pi}(X_i) (Goplerud et al. 2025). These are also averaged together to return an estimate to produce a population-level effect.

Second, one can estimate conditional average marginal effects using HTE_by_moderator. This takes a moderator such as party identification and counterfactually sets each observation to some level (e.g., "Strong Democrat"). It then reports the average of the individual-level conditional effects across the sample population as the "conditional" average marginal effect. If overall_AME is true, it also returns the average of the individual heterogeneous effects given the observed distribution of pre-treatment moderators. It and the population element of the list produced by HTE_by_individual coincide exactly.

Both functions can be used with split-sample or refit, i.e. FactorHet_refit, and the computed AME, although this will not take into account uncertainty in the moderator estimation as they are assumed fixed when refitting the model.

To use these functions, first estimate the AMEs by group, i.e., using AME and then pass this object and the original FactorHet model to the functions for computing heterogeneous effects by moderator or individual.

Value

HTE_by_individual returns a list with two data.frames. The first individual contains the estimated individual conditional average marginal effects. The second population contains the average of those individual effects. Standard errors (via the column var) are also included.

HTE_by_population returns a list for each moderator that consists itself of a list of each value of the moderator used. The value "out" contains the conditional average marginal effects.

Examples


data(immigration)
# Estimate model with arbitrary choice of lambda
fit <- FactorHet(Chosen_Immigrant ~ Plans + Ed + Country,
  design = immigration, lambda = 1e-2,
  moderator = ~ party_ID,
  K = 2, group = ~ CaseID,
  control = FactorHet_control(init = 'mclust'),
  task = ~ contest_no, choice_order = ~ choice_id)
# Estimate AME 
est_AME <- AME(fit)
# Get individual AME; note only seven distinct
# patterns will exist as partyID is the only (discrete)
# moderator
iAME <- HTE_by_individual(
  object = fit,
  AME = est_AME)
# Get conditional AME by level of party ID
cAME_pID <- HTE_by_moderator(
  object = fit,
  AME = est_AME, overall_AME = TRUE)

AME_1 <- cAME_pID$`Overall AME`$out[[1]][,c('factor', 'level', 'est', 'var')]
AME_2 <- iAME$population[,c('factor', 'level', 'est', 'var')]
rownames(AME_1) <- rownames(AME_2) <- NULL
stopifnot(isTRUE(all.equal(AME_1, AME_2)))


[Package FactorHet version 1.0.0 Index]