out <- hbal(Treat = 'D', X = c('X1', 'X2'), Y = 'Y', data = dat,
expand.degree = 3, cv = TRUE, group.exact = c(1, 1, 0, 0, 0))
#> Crossvalidation...
summary(out)
#> Call:
#> hbal(data = dat, Treat = "D", X = c("X1", "X2"), Y = "Y", expand.degree = 3,
#> cv = TRUE, group.exact = c(1, 1, 0, 0, 0))
#>
#> Treated Controls
#> 256 1244
#> Co/Tr Ratio = 4.86
#>
#> Groups
#> #Terms Penalty
#> linear 2 0.0
#> two-way 1 0.0
#> squared 2 0.0
#> squared*linear 2 0.0
#> cubic 2 4.7
#>
#> Balance Table
#> Tr.Mean Co.Mean W.Co.Mean Std.Diff.(O) Std.Diff.(W)
#> X1 0.35 -0.11 0.35 0.46 0.00
#> X2 0.42 -0.07 0.42 0.49 0.00
#> X1.X2 0.24 -0.10 0.24 0.32 0.00
#> X1.X1 1.01 1.01 1.01 0.00 0.00
#> X2.X2 0.99 0.99 0.99 0.00 0.00
#> X1.X1.X2 0.32 -0.01 0.32 0.18 0.00
#> X1.X2.X2 0.32 -0.17 0.32 0.29 0.00
#> X1.X1.X1 0.93 -0.25 1.02 0.30 -0.02
#> X2.X2.X2 1.16 -0.23 0.95 0.40 0.063 Additional Options
3.1 Controlling Exact/Approximate Balancing
Users can manually control which group of covariates to be exactly balanced and which group to be approximately balanced (via regularization) by using the group.exact argument. It takes in a binary vector with length equal to the number of covariate groups, with 1 indicating exact balance on that group and 0 indicating approximate balance. Appropriate penalties are then searched through cross-validation. When using this option, please make that the length of vector supplied equals the number of groups.
For example, we can ask hbal() to achieve exact balance on the linear terms and two-way interactions and approximate balance for the rest:
3.2 User-Supplied Penalties
If researchers have prior knowledge about covariates and would like to supply specific penalties for each group of covariates, we can do so by passing a vector of penalties to the group.alpha argument. For example, we can manually set penalties to be 0 for the the linear terms and two-way interactions and 100 for other groups:
out <- hbal(Treat = 'D', X = c('X1', 'X2', 'X3'), Y = 'Y', data = dat,
expand.degree = 3, group.alpha = c(0, 0, 100, 100, 100, 100))
summary(out)
#> Call:
#> hbal(data = dat, Treat = "D", X = c("X1", "X2", "X3"), Y = "Y",
#> expand.degree = 3, group.alpha = c(0, 0, 100, 100, 100, 100))
#>
#> Treated Controls
#> 256 1244
#> Co/Tr Ratio = 4.86
#>
#> Groups
#> #Terms Penalty
#> linear 3 0
#> two-way 3 0
#> squared 2 100
#> three-way 1 100
#> squared*linear 4 100
#> cubic 2 100
#>
#> Balance Table
#> Tr.Mean Co.Mean W.Co.Mean Std.Diff.(O) Std.Diff.(W)
#> X1 0.35 -0.11 0.35 0.46 0.00
#> X2 0.42 -0.07 0.42 0.49 0.00
#> X3 0.52 0.51 0.52 0.02 0.00
#> X1.X2 0.24 -0.10 0.24 0.32 0.00
#> X1.X3 0.07 -0.02 0.07 0.12 0.00
#> X2.X3 0.21 -0.01 0.21 0.33 0.00
#> X1.X1 1.01 1.01 1.18 0.00 -0.12
#> X2.X2 0.99 0.99 1.06 0.00 -0.06
#> X1.X2.X3 0.13 0.00 0.14 0.18 -0.02
#> X1.X1.X2 0.32 -0.01 0.52 0.18 -0.11
#> X1.X2.X2 0.32 -0.17 0.37 0.29 -0.03
#> X1.X1.X3 0.55 0.52 0.58 0.03 -0.03
#> X2.X2.X3 0.50 0.47 0.55 0.02 -0.06
#> X1.X1.X1 0.93 -0.25 1.06 0.30 -0.03
#> X2.X2.X2 1.16 -0.23 1.03 0.40 0.043.3 Controlling Serial Expansion
Sometimes we may not want to perform serial expansion on all covariates but instead expand on a select set of covariates, we can do so by using the X.expand argument to specify the covariates we want to expand on. For example, we can expand only on X1:
out <- hbal(Treat = 'D', X = c('X1', 'X2', 'X3'), Y = 'Y', data = dat,
expand.degree = 3, X.expand = c('X1', 'X2'))
summary(out)
#> Call:
#> hbal(data = dat, Treat = "D", X = c("X1", "X2", "X3"), Y = "Y",
#> X.expand = c("X1", "X2"), expand.degree = 3)
#>
#> Treated Controls
#> 256 1244
#> Co/Tr Ratio = 4.86
#>
#> Groups
#> #Terms Penalty
#> linear 3 0
#> two-way 1 0
#> squared 2 0
#> squared*linear 2 0
#> cubic 2 0
#>
#> Balance Table
#> Tr.Mean Co.Mean W.Co.Mean Std.Diff.(O) Std.Diff.(W)
#> X1 0.35 -0.11 0.35 0.46 0
#> X2 0.42 -0.07 0.42 0.49 0
#> X3 0.52 0.51 0.52 0.02 0
#> X1.X2 0.24 -0.10 0.24 0.32 0
#> X1.X1 1.01 1.01 1.01 0.00 0
#> X2.X2 0.99 0.99 0.99 0.00 0
#> X1.X1.X2 0.32 -0.01 0.32 0.18 0
#> X1.X2.X2 0.32 -0.17 0.32 0.29 0
#> X1.X1.X1 0.93 -0.25 0.93 0.30 0
#> X2.X2.X2 1.16 -0.23 1.16 0.40 03.4 Selecting Covariates
Performing serial expansion on many covariates can result in a prohibitive number of covariates that need to be balanced on. In such cases, users many want to reduce the number of covariates by using the double selection method by Belloni et al. (2014). This screens the expanded covariates and only keeps those that are predictive for the treatment assignment or the outcome. Users can enable double selection by setting ds = TRUE. In the following case, almost all the higher-order terms except X1*X2 and X2*X3 are screened out by the double selection procedure.
out <- hbal(Treat = 'D', X = c('X1', 'X2', 'X3'), Y = 'Y', data = dat,
expand.degree = 3, ds = TRUE)
summary(out)
#> Call:
#> hbal(data = dat, Treat = "D", X = c("X1", "X2", "X3"), Y = "Y",
#> expand.degree = 3, ds = TRUE)
#>
#> Treated Controls
#> 256 1244
#> Co/Tr Ratio = 4.86
#>
#> Groups
#> #Terms Penalty
#> linear 2 0
#> two-way 2 0
#>
#> Balance Table
#> Tr.Mean Co.Mean W.Co.Mean Std.Diff.(O) Std.Diff.(W)
#> X1 0.35 -0.11 0.35 0.46 0
#> X2 0.42 -0.07 0.41 0.49 0
#> X1.X2 0.24 -0.10 0.24 0.32 0
#> X2.X3 0.21 -0.01 0.21 0.33 0
att(out)3.5 Keeping/Excluding Covariates
If there are covariates that users would like to keep in the balancing conditions regardless of whether they are selected in double selection, we can use the X.keep argument to specify the covariates to keep. On the other hand, if a priori we know some combinations of the covariates are nonsensical, we can exclude them explicitly by using the exclude argument. For example, we can exclude any interaction that involves X1 and X2:
out <- hbal(Treat = 'D', X = c('X1', 'X2', 'X3'), Y = 'Y', data = dat,
expand.degree = 3, exclude = list(c('X1', 'X2')))
summary(out) # X1.X2 and X1.X1.X2 removed from balancing scheme
#> Call:
#> hbal(data = dat, Treat = "D", X = c("X1", "X2", "X3"), Y = "Y",
#> expand.degree = 3, exclude = list(c("X1", "X2")))
#>
#> Treated Controls
#> 256 1244
#> Co/Tr Ratio = 4.86
#>
#> Groups
#> #Terms Penalty
#> linear 3 0
#> two-way 2 0
#> squared 2 0
#> squared*linear 2 0
#> cubic 2 0
#>
#> Balance Table
#> Tr.Mean Co.Mean W.Co.Mean Std.Diff.(O) Std.Diff.(W)
#> X1 0.35 -0.11 0.35 0.46 0
#> X2 0.42 -0.07 0.42 0.49 0
#> X3 0.52 0.51 0.52 0.02 0
#> X1.X3 0.07 -0.02 0.07 0.12 0
#> X2.X3 0.21 -0.01 0.21 0.33 0
#> X1.X1 1.01 1.01 1.01 0.00 0
#> X2.X2 0.99 0.99 0.99 0.00 0
#> X1.X1.X3 0.55 0.52 0.55 0.03 0
#> X2.X2.X3 0.50 0.47 0.50 0.02 0
#> X1.X1.X1 0.93 -0.25 0.93 0.30 0
#> X2.X2.X2 1.16 -0.23 1.16 0.40 0
att(out)