make_model
uses dagitty syntax and functionality to
specify nodes and edges of a graph. Implied causal types are calculated
and default priors are provided under the assumption of no confounding.
Models can be updated with specification of a parameter matrix, P
, by
providing restrictions on causal types, and/or by providing informative
priors on parameters. The default setting for a causal model have flat
(uniform) priors and parameters putting equal weight on each parameter
within each parameter set. These can be adjust with set_priors
and set_parameters
Arguments
- statement
A character. Statement describing causal relations using dagitty syntax. Only directed relations are permitted. For instance "X -> Y" or "X1 -> Y <- X2; X1 -> X2".
- add_causal_types
Logical. Whether to create and attach causal types to
model
. Defaults to `TRUE`.- nodal_types
List of nodal types associated with model nodes
Value
An object of class causal_model
.
An object of class "causal_model"
is a list containing at least the
following components:
- statement
A character vector of the statement that defines the model
- dag
A
data.frame
with columns `parent`and `children` indicating how nodes relate to each other.- nodes
A named
list
with the nodes in the model- parents_df
A
data.frame
listing nodes, whether they are root nodes or not, and the number of parents they have- nodal_types
Optional: A named
list
with the nodal types in the model. List should be ordered according to the causal ordering of nodes. If NULL nodal types are generated. If FALSE, a parameters data frame is not generated.- parameters_df
A
data.frame
with descriptive information of the parameters in the model- causal_types
A
data.frame
listing causal types and the nodal types that produce them
See also
summary.causal_model
provides summary method for
output objects of class causal_model
Examples
make_model(statement = "X -> Y")
#>
#> Statement:
#> X -> Y
#>
#> Number of types by node:
#> X Y
#> 2 4
#>
#> Number of unit types: 8
#>
modelXKY <- make_model("X -> K -> Y; X -> Y")
# Example where cyclicaly dag attempted
if (FALSE) {
modelXKX <- make_model("X -> K -> X")
}
# Examples with confounding
model <- make_model("X->Y; X <-> Y")
model$P
#>
#> Rows are parameters, grouped in parameter sets
#>
#> Columns are causal types
#>
#> Cell entries indicate whether a parameter probability isused
#> in the calculation of causal type probability
#>
#> X0.Y00 X1.Y00 X0.Y10 X1.Y10 X0.Y01 X1.Y01 X0.Y11 X1.Y11
#> X.0 1 0 1 0 1 0 1 0
#> X.1 0 1 0 1 0 1 0 1
#> Y.00_X.0 1 0 0 0 0 0 0 0
#> Y.10_X.0 0 0 1 0 0 0 0 0
#> Y.01_X.0 0 0 0 0 1 0 0 0
#> Y.11_X.0 0 0 0 0 0 0 1 0
#> Y.00_X.1 0 1 0 0 0 0 0 0
#> Y.10_X.1 0 0 0 1 0 0 0 0
#> Y.01_X.1 0 0 0 0 0 1 0 0
#> Y.11_X.1 0 0 0 0 0 0 0 1
#>
#>
#> param_set (P)
#> X Y.X.0 Y.X.1
model <- make_model("Y2 <- X -> Y1; X <-> Y1; X <-> Y2")
dim(model$P)
#> [1] 18 32
model$P
#>
#> Rows are parameters, grouped in parameter sets
#>
#> Columns are causal types
#>
#> Cell entries indicate whether a parameter probability isused
#> in the calculation of causal type probability
#>
#> X0.Y100.Y200 X1.Y100.Y200 X0.Y110.Y200 X1.Y110.Y200 X0.Y101.Y200
#> X.0 1 0 1 0 1
#> X.1 0 1 0 1 0
#> Y1.00_X.0 1 0 0 0 0
#> Y1.10_X.0 0 0 1 0 0
#> Y1.01_X.0 0 0 0 0 1
#> Y1.11_X.0 0 0 0 0 0
#> Y1.00_X.1 0 1 0 0 0
#> Y1.10_X.1 0 0 0 1 0
#> Y1.01_X.1 0 0 0 0 0
#> Y1.11_X.1 0 0 0 0 0
#> Y2.00_X.0 1 0 1 0 1
#> Y2.10_X.0 0 0 0 0 0
#> Y2.01_X.0 0 0 0 0 0
#> Y2.11_X.0 0 0 0 0 0
#> Y2.00_X.1 0 1 0 1 0
#> Y2.10_X.1 0 0 0 0 0
#> Y2.01_X.1 0 0 0 0 0
#> Y2.11_X.1 0 0 0 0 0
#> X1.Y101.Y200 X0.Y111.Y200 X1.Y111.Y200 X0.Y100.Y210 X1.Y100.Y210
#> X.0 0 1 0 1 0
#> X.1 1 0 1 0 1
#> Y1.00_X.0 0 0 0 1 0
#> Y1.10_X.0 0 0 0 0 0
#> Y1.01_X.0 0 0 0 0 0
#> Y1.11_X.0 0 1 0 0 0
#> Y1.00_X.1 0 0 0 0 1
#> Y1.10_X.1 0 0 0 0 0
#> Y1.01_X.1 1 0 0 0 0
#> Y1.11_X.1 0 0 1 0 0
#> Y2.00_X.0 0 1 0 0 0
#> Y2.10_X.0 0 0 0 1 0
#> Y2.01_X.0 0 0 0 0 0
#> Y2.11_X.0 0 0 0 0 0
#> Y2.00_X.1 1 0 1 0 0
#> Y2.10_X.1 0 0 0 0 1
#> Y2.01_X.1 0 0 0 0 0
#> Y2.11_X.1 0 0 0 0 0
#> X0.Y110.Y210 X1.Y110.Y210 X0.Y101.Y210 X1.Y101.Y210 X0.Y111.Y210
#> X.0 1 0 1 0 1
#> X.1 0 1 0 1 0
#> Y1.00_X.0 0 0 0 0 0
#> Y1.10_X.0 1 0 0 0 0
#> Y1.01_X.0 0 0 1 0 0
#> Y1.11_X.0 0 0 0 0 1
#> Y1.00_X.1 0 0 0 0 0
#> Y1.10_X.1 0 1 0 0 0
#> Y1.01_X.1 0 0 0 1 0
#> Y1.11_X.1 0 0 0 0 0
#> Y2.00_X.0 0 0 0 0 0
#> Y2.10_X.0 1 0 1 0 1
#> Y2.01_X.0 0 0 0 0 0
#> Y2.11_X.0 0 0 0 0 0
#> Y2.00_X.1 0 0 0 0 0
#> Y2.10_X.1 0 1 0 1 0
#> Y2.01_X.1 0 0 0 0 0
#> Y2.11_X.1 0 0 0 0 0
#> X1.Y111.Y210 X0.Y100.Y201 X1.Y100.Y201 X0.Y110.Y201 X1.Y110.Y201
#> X.0 0 1 0 1 0
#> X.1 1 0 1 0 1
#> Y1.00_X.0 0 1 0 0 0
#> Y1.10_X.0 0 0 0 1 0
#> Y1.01_X.0 0 0 0 0 0
#> Y1.11_X.0 0 0 0 0 0
#> Y1.00_X.1 0 0 1 0 0
#> Y1.10_X.1 0 0 0 0 1
#> Y1.01_X.1 0 0 0 0 0
#> Y1.11_X.1 1 0 0 0 0
#> Y2.00_X.0 0 0 0 0 0
#> Y2.10_X.0 0 0 0 0 0
#> Y2.01_X.0 0 1 0 1 0
#> Y2.11_X.0 0 0 0 0 0
#> Y2.00_X.1 0 0 0 0 0
#> Y2.10_X.1 1 0 0 0 0
#> Y2.01_X.1 0 0 1 0 1
#> Y2.11_X.1 0 0 0 0 0
#> X0.Y101.Y201 X1.Y101.Y201 X0.Y111.Y201 X1.Y111.Y201 X0.Y100.Y211
#> X.0 1 0 1 0 1
#> X.1 0 1 0 1 0
#> Y1.00_X.0 0 0 0 0 1
#> Y1.10_X.0 0 0 0 0 0
#> Y1.01_X.0 1 0 0 0 0
#> Y1.11_X.0 0 0 1 0 0
#> Y1.00_X.1 0 0 0 0 0
#> Y1.10_X.1 0 0 0 0 0
#> Y1.01_X.1 0 1 0 0 0
#> Y1.11_X.1 0 0 0 1 0
#> Y2.00_X.0 0 0 0 0 0
#> Y2.10_X.0 0 0 0 0 0
#> Y2.01_X.0 1 0 1 0 0
#> Y2.11_X.0 0 0 0 0 1
#> Y2.00_X.1 0 0 0 0 0
#> Y2.10_X.1 0 0 0 0 0
#> Y2.01_X.1 0 1 0 1 0
#> Y2.11_X.1 0 0 0 0 0
#> X1.Y100.Y211 X0.Y110.Y211 X1.Y110.Y211 X0.Y101.Y211 X1.Y101.Y211
#> X.0 0 1 0 1 0
#> X.1 1 0 1 0 1
#> Y1.00_X.0 0 0 0 0 0
#> Y1.10_X.0 0 1 0 0 0
#> Y1.01_X.0 0 0 0 1 0
#> Y1.11_X.0 0 0 0 0 0
#> Y1.00_X.1 1 0 0 0 0
#> Y1.10_X.1 0 0 1 0 0
#> Y1.01_X.1 0 0 0 0 1
#> Y1.11_X.1 0 0 0 0 0
#> Y2.00_X.0 0 0 0 0 0
#> Y2.10_X.0 0 0 0 0 0
#> Y2.01_X.0 0 0 0 0 0
#> Y2.11_X.0 0 1 0 1 0
#> Y2.00_X.1 0 0 0 0 0
#> Y2.10_X.1 0 0 0 0 0
#> Y2.01_X.1 0 0 0 0 0
#> Y2.11_X.1 1 0 1 0 1
#> X0.Y111.Y211 X1.Y111.Y211
#> X.0 1 0
#> X.1 0 1
#> Y1.00_X.0 0 0
#> Y1.10_X.0 0 0
#> Y1.01_X.0 0 0
#> Y1.11_X.0 1 0
#> Y1.00_X.1 0 0
#> Y1.10_X.1 0 0
#> Y1.01_X.1 0 0
#> Y1.11_X.1 0 1
#> Y2.00_X.0 0 0
#> Y2.10_X.0 0 0
#> Y2.01_X.0 0 0
#> Y2.11_X.0 1 0
#> Y2.00_X.1 0 0
#> Y2.10_X.1 0 0
#> Y2.01_X.1 0 0
#> Y2.11_X.1 0 1
#>
#>
#> param_set (P)
#> X Y1.X.0 Y1.X.1 Y2.X.0 Y2.X.1
model <- make_model("X1 -> Y <- X2; X1 <-> Y; X2 <-> Y")
dim(model$P)
#> [1] 68 64
model$parameters_df
#> Mapping of model parameters to nodal types:
#>
#> ----------------------------------------------------------------
#>
#> param_names: name of parameter
#> node: name of endogeneous node associated with the parameter
#> gen: partial causal ordering of the parameter's node
#> param_set: parameter groupings forming a simplex
#> given: if model has confounding gives conditioning nodal type
#> param_value: parameter values
#> priors: hyperparameters of the prior Dirichlet distribution
#>
#> ----------------------------------------------------------------
#>
#>
#> first 10 rows:
#> param_names node gen param_set nodal_type given param_value
#> 1 X1.0 X1 1 X1 0 0.5000
#> 2 X1.1 X1 1 X1 1 0.5000
#> 3 X2.0 X2 2 X2 0 0.5000
#> 4 X2.1 X2 2 X2 1 0.5000
#> 5 Y.0000_X1.0_X2.0 Y 3 Y.X1.0.X2.0 0000 X1.0, X2.0 0.0625
#> 6 Y.1000_X1.0_X2.0 Y 3 Y.X1.0.X2.0 1000 X1.0, X2.0 0.0625
#> 7 Y.0100_X1.0_X2.0 Y 3 Y.X1.0.X2.0 0100 X1.0, X2.0 0.0625
#> 8 Y.1100_X1.0_X2.0 Y 3 Y.X1.0.X2.0 1100 X1.0, X2.0 0.0625
#> 9 Y.0010_X1.0_X2.0 Y 3 Y.X1.0.X2.0 0010 X1.0, X2.0 0.0625
#> 10 Y.1010_X1.0_X2.0 Y 3 Y.X1.0.X2.0 1010 X1.0, X2.0 0.0625
#> priors
#> 1 1
#> 2 1
#> 3 1
#> 4 1
#> 5 1
#> 6 1
#> 7 1
#> 8 1
#> 9 1
#> 10 1
# A single node graph is also possible
model <- make_model("X")
# Unconnected nodes not allowed
if (FALSE) {
model <- make_model("X <-> Y")
}
nodal_types <-
list(
A = c("0","1"),
B = c("0","1"),
C = c("0","1"),
D = c("0","1"),
E = c("0","1"),
Y = c(
"00000000000000000000000000000000",
"01010101010101010101010101010101",
"00110011001100110011001100110011",
"00001111000011110000111100001111",
"00000000111111110000000011111111",
"00000000000000001111111111111111",
"11111111111111111111111111111111" ))
make_model("A -> Y; B ->Y; C->Y; D->Y; E->Y",
nodal_types = nodal_types)$parameters_df
#> Mapping of model parameters to nodal types:
#>
#> ----------------------------------------------------------------
#>
#> param_names: name of parameter
#> node: name of endogeneous node associated with the parameter
#> gen: partial causal ordering of the parameter's node
#> param_set: parameter groupings forming a simplex
#> given: if model has confounding gives conditioning nodal type
#> param_value: parameter values
#> priors: hyperparameters of the prior Dirichlet distribution
#>
#> ----------------------------------------------------------------
#>
#>
#> first 10 rows:
#> param_names node gen param_set nodal_type given param_value priors
#> 1 A.0 A 1 A 0 0.5 1
#> 2 A.1 A 1 A 1 0.5 1
#> 3 B.0 B 2 B 0 0.5 1
#> 4 B.1 B 2 B 1 0.5 1
#> 5 C.0 C 3 C 0 0.5 1
#> 6 C.1 C 3 C 1 0.5 1
#> 7 D.0 D 4 D 0 0.5 1
#> 8 D.1 D 4 D 1 0.5 1
#> 9 E.0 E 5 E 0 0.5 1
#> 10 E.1 E 5 E 1 0.5 1
nodal_types = list(Y = c("01", "10"), Z = c("0", "1"))
make_model("Z -> Y", nodal_types = nodal_types)$parameters_df
#> Ordering of provided nodal types is being altered to match generation
#> Mapping of model parameters to nodal types:
#>
#> ----------------------------------------------------------------
#>
#> param_names: name of parameter
#> node: name of endogeneous node associated with the parameter
#> gen: partial causal ordering of the parameter's node
#> param_set: parameter groupings forming a simplex
#> given: if model has confounding gives conditioning nodal type
#> param_value: parameter values
#> priors: hyperparameters of the prior Dirichlet distribution
#>
#> ----------------------------------------------------------------
#>
#> param_names node gen param_set nodal_type given param_value priors
#> 1 Z.0 Z 1 Z 0 0.5 1
#> 2 Z.1 Z 1 Z 1 0.5 1
#> 3 Y.01 Y 2 Y 01 0.5 1
#> 4 Y.10 Y 2 Y 10 0.5 1
make_model("Z -> Y", nodal_types = FALSE)$parents_df
#> Model not properly defined: nodal_types should be NULL or specified for all nodes in model: Z, Y
#> node root parents parent_nodes
#> 1 Z TRUE 0
#> 2 Y FALSE 1 Z