# Modeling Causal Complexity

### Description

Boolean binary response models are a family of partial-observability binary response models designed to permit researchers to model causal complexity, or multiple causal “paths” to a given outcome.

### Details

Boolean permits estimation of Boolean binary response models (see
Braumoeller 2003 for derivation), which are a family of
partial-observability n-variate models designed to permit researchers to
model causal complexity, or multiple causal “paths” to a given
outcome. The various “paths” are modeled as latent dependent variables
that are multiplied together in a manner determined by the logic of their
(Boolean) interaction. If, for example, we wanted to model a situation in
which diet OR smoking causes heart failure, we would use one set of
independent variables (caloric intake, fat intake, etc.) to predict the
latent probability of diet-related coronary failure (*y1^**), use
another set of variables (cigarettes smoked per day, exposure to second-hand
smoke, etc.) to predict the latent probability of smoking-related coronary
failure (*y2^**), and model the observed outcome (*y*, or coronary
failure) as a function of the Boolean interaction of the two: *\Pr(y=1) =
1-([1-y1^*] \times [1-y2^*])*. Independent variables that have an impact on both
latent dependent variables can be included in both paths. Any combination of
any number of ANDs and ORs can be modeled, though the procedure becomes
exponentially more data-intensive as the number of interactions increases.

Package: | boolean3 |

Type: | Package |

Version: | 3.1.6 |

Date: | 2014-11-15 |

License: | GPL-3 |

LazyLoad: | yes |

### Note

`boolean3`

was developed by Jason W. Morgan under the direction
of Bear Braumoeller with support from The Ohio State University's College of
Social and Behavioral Sciences. The package represents a significant
re-write of the original `boolean`

implementation developed by Bear
Braumoeller, Ben Goodrich, and Jacob Kline. Please see the release notes and
accompanying documentation for details regarding the many changes made in
this version.

### Author(s)

Jason W. Morgan (morgan.746@osu.edu)

### References

Braumoeller, Bear F. (2003) “Causal Complexity and the Study of
Politics.” *Political Analysis* 11(3): 209–233.

### See Also

See `boolprep`

for model setup and
`boolean`

for estimation.

### Examples

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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | ```
## Generate some fake data
require(mvtnorm)
set.seed(12345)
N <- 2000
Df <- cbind(1, rmvnorm(N, mean=rep(0, 5)))
## Set coefficients
beta.a <- c(-2.00, 0.33, 0.66, 1.00)
beta.b <- c(0.00, 1.50, -0.25)
## Generate path probabilities following a normal model.
y.a <- as.vector(pnorm(tcrossprod(beta.a, Df[, 1:4])))
y.b <- as.vector(pnorm(tcrossprod(beta.b, Df[, c(1, 5, 6)])))
## AND and OR-model
or <- function(x, y) { x + y - x * y }
and <- function(x, y) { x * y }
y.star.OR <- or(y.a, y.b)
y.star.AND <- and(y.a, y.b)
## Observed responses
y.OR <- rbinom(N, 1, y.star.OR)
y.AND <- rbinom(N, 1, y.star.AND)
## Set up data.frame for estimation
Df <- cbind(1, Df)
Df <- as.data.frame(Df)
Df[,1] <- y.OR
Df[,2] <- y.AND
names(Df) <- c("y.OR", "y.AND", "x1", "x2", "x3", "x4", "x5")
## Before estimating, boolean models need to be specified using the
## boolprep function.
## OR model, specified to use a probit link for each causal path. This
## matches the data generating process above.
mod.OR <- boolprep(y.OR ~ (a | b), a ~ x1 + x2 + x3, b ~ x4 + x5,
data = Df, family=list(binomial("probit")))
## IF you really want to, it's also possible to specify a different
## link function for each causal path. These should be in the same
## order as specified in the model formula.
mod.OR2 <- boolprep(y.OR ~ (a | b), a ~ x1 + x2 + x3, b ~ x4 + x5,
data = Df, family=list(binomial("probit"),
binomial("logit")))
## Fit the prepared model using the nlminb optimizer (the default).
(fit.OR <- boolean(mod.OR, method="nlminb", control=list(trace=1)))
## Multiple optimizers can be specified in a single call to boolean.
## Here we fit with the nlm and nlminb optimizers.
(fit1.OR <- boolean(mod.OR, method=c("nlm", "nlminb")))
## Re-fit, with BFGS and a higher maximum number of iterations. All
## of the options that go along with nlm(), optim(), and genoud() should
## be transparently passable through boolean.
(fit2.OR <- boolean(mod.OR, method="BFGS", control = list(maxit = 500)))
## Induce a convergence warning message.
(fit3.OR <- boolean(mod.OR, method="BFGS", control = list(maxit = 5)))
## Not run:
## Now estimate model with genoud, a genetic optimizer. This has the
## capability of using multiple processors via parallel.
(fit6.OR <- boolean(mod.OR, method="genoud",
cluster=c("localhost", "localhost"),
print.level=2))
## The default SANN optimizer is also available.
(fit7.OR <- boolean(mod.OR, method="SANN"))
## End(Not run)
## The fit is stored as "model.fit", within the boolean object.
str(fit.OR$model.fit)
## Create a summary object, saving and printing it. Then take a look at
## the objects stored in the summary object.
(smry <- summary(fit.OR))
str(smry)
## Extract log-likelihood and coefficient vector.
logLik(fit.OR)
coef(fit.OR)
## Not run:
## Display the contours of the likelihood given a change the value of
## the coefficients. Despite the function name, these are not true
## profile likelihoods as they hold all other coefficients fixed at
## their MLE.
(prof <- boolprof(fit.OR))
## Extract the plots for x1_a and x4_b.
plot(prof, y = c("x1_a", "x4_b"))
plot(prof, y = c(1, 3), scales = list(y = list(relation = "free")))
## You can also use variable or index matching with boolprof to select
## particular covariates of interest.
boolprof(fit.OR, vars = c(1, 3))
boolprof(fit.OR, vars = c("x1_a", "x4_b"))
## Plots of predicted probabilities are available through boolprob.
## With boolprob, either vars or newdata *must* be specified.
boolprob(fit.OR, vars = c("x1_a", "x4_b"))
boolprob(fit.OR, vars = c(2, 3, 4, 6))
## Specifying conf.int = TRUE produces simulated confidence intervals.
## The number of samples to pull from the distribution of the estimated
## coefficients is controlled by n; n=100 is default. This can take a
## while.
(prob <- boolprob(fit.OR, vars = c(2, 3, 4, 6), n = 1000,
conf.int = TRUE))
## Choose a different method estimate upon which to base the estimates.
(prob <- boolprob(fit1.OR, method="nlm", vars=c(2, 3, 4, 6), n=1000,
conf.int=TRUE))
## As with the other components of the model, you can extract the
## predicted probabilities.
str(prob)
prob$est
## Bootstrapping is also possible, and is the recommended method of
## making inferences. The boolbool function uses a simple sampling scheme:
## it resamples repeatedly from the provided data.frame. More the complex
## data structures with, for example, clustering, need to be dealt with
## manually.
(bs <- boolboot(fit, n=10))
## boolboot supports bootstrapping across multiple processors.
(bs <- boolboot(fit, n=100, cluster=c("localhost", "localhost")))
## End(Not run)
``` |