# A simple back-door formula
data1 <- "P(x,y,z)"
query1 <- "P(y|do(x))"
graph1 <- "
x -> y
z -> x
z -> y
"
dosearch(data1, query1, graph1)
# A simple front-door formula
data2 <- "P(x,y,z)"
query2 <- "P(y|do(x))"
graph2 <- "
x -> z
z -> y
x <-> y
"
dosearch(data2, query2, graph2)
# A scenario with combined transportability and selection bias
# in this case using the search heuristic provides a simpler formula
data <- "
p(x,z,y|s)
p(y,z|t,do(x))
"
query <- "p(y|do(x))"
graph <- "
x -> z
z -> y
x -> s
t -> z
x <-> y
"
dosearch(
data,
query,
graph,
transportability = "t",
selection_bias = "s",
control = list(heuristic = TRUE, improve = FALSE)
)
# A simple case-control design
data <- "
p(x*,y*,r_x,r_y)
p(y)
"
graph <- "
x -> y
y -> r_y
r_y -> r_x
"
md <- "r_x : x, r_y : y"
dosearch(data, query, graph, missing_data = md)
# Graph input using 'igraph' in the 'causaleffect' syntax
if (requireNamespace("igraph", quietly = TRUE)) {
g_igraph <- igraph::graph.formula(
x -+ z, z -+ y, x -+ y, y -+ x,
simplify = FALSE
)
g_igraph <- igraph::set.edge.attribute(g_igraph, "description", 3:4, "U")
dosearch(data2, query2, g_igraph)
}
# Graph input with 'dagitty'
if (requireNamespace("dagitty", quietly = TRUE)) {
g_dagitty <- dagitty::dagitty("dag{x -> z -> y; x <-> y}")
dosearch(data2, query2, g_dagitty)
}
# Alternative distribution input style using lists and vectors:
# Each element of the list describes a single distribution
# Each element is a character vector that describes the role
# of each variable in the distribution as follows:
# For a variable V and a distribution P(A|do(B),C) we have
# V = 0, if V is in A
# V = 1, if V is in B
# V = 2, if V is in C
data_alt <- list(
c(x = 0, y = 0, z = 0) # = P(x,y,z)
)
query_alt <- c(x = 1, y = 0) # = P(y|do(x))
dosearch(data_alt, query_alt, graph2)
if (FALSE) {
# Additional examples
# Multiple input distributions (both observational and interventional)
data3 <- "
p(z_2,x_2|do(x_1))
p(z_1|x_2,do(x_1,y))
p(x_1|w_1,do(x_2))
p(y|z_1,z_2,x_1,do(x_2))
p(w|y,x_1,do(x_2))
"
query3 <- "p(y,x_1|w,do(x_2))"
graph3 <- "
x_1 -> z_2
x_1 -> z_1
x_2 -> z_1
x_2 -> z_2
z_1 -> y
z_2 -> y
x_1 -> w
x_2 -> w
z_1 -> w
z_2 -> w
"
dosearch(data3, query3, graph3)
# Selection bias
data4 <- "
p(x,y,z_1,z_2|s)
p(z_1,z_2)
"
query4 <- "p(y|do(x))"
graph4 <- "
x -> z_1
z_1 -> z_2
x -> y
y -- z_2
z_2 -> s
"
dosearch(data4, query4, graph4, selection_bias = "s")
# Transportability
data5 <- "
p(x,y,z_1,z_2)
p(x,y,z_1|t_1,t_2,do(z_2))
p(x,y,z_2|t_3,do(z_1))
"
query5 <- "p(y|do(x))"
graph5 <- "
z_1 -> x
x -> z_2
z_2 -> y
z_1 <-> x
z_1 <-> z_2
z_1 <-> y
t_1 -> z_1
t_2 -> z_2
t_3 -> y
"
dosearch(data5, query5, graph5, transportability = "t_1, t_2, t_3")
# Missing data
# Proxy variables are denoted by an asterisk (*)
data6 <- "
p(x*,y*,z*,m_x,m_y,m_z)
"
query6 <- "p(x,y,z)"
graph6 <- "
z -> x
x -> y
x -> m_z
y -> m_z
y -> m_x
z <-> y
"
dosearch(data6, query6, graph6, missing_data = "m_x : x, m_y : y, m_z : z")
# An LDAG
data7 <- "P(X,Y,Z)"
query7 <- "P(Y|X,I_X=1)"
graph7 <- "
X -> Y : Z = 1
Z -> Y
Z -> X : I_X = 1
I_X -> X
H -> X : I_X = 1
H -> Z
Q -> Z
Q -> Y : Z = 0
"
dosearch(data7, query7, graph7)
# A more complicated LDAG
# with multiple assignments for the edge X -> Z
data8 <- "P(X,Y,Z,A,W)"
query8 <- "P(Y|X,I_X=1)"
graph8 <- "
I_X -> X
I_Z -> Z
A -> W
Z -> Y
A -> Z
X -> Z : I_Z = 1; A = 1
X -> Y : A = 0
W -> X : I_X = 1
W -> Y : A = 0
A -> Y
U -> X : I_X = 1
U -> Y : A = 1
"
dosearch(data8, query8, graph8)
# Export the DOT diagram of the derivation as an SVG file
# to the working directory via the DOT package.
# By default, only the identifying part is plotted.
# PostScript format is also supported.
if (requireNamespace("DOT", quietly = TRUE)) {
d <- get_derivation(
data1,
query1,
graph1,
control = list(draw_derivation = TRUE)
)
DOT::dot(d$derivation, "derivation.svg")
}
}
data <- "p(x,y,z)"
query <- "p(y|do(x))"
graph <- "
x -> y
Z -> x
z -> y
"
x <- dosearch(data, query, graph)
y <- summary(x)
if (FALSE) {
out <- dosearch(
"p(x,y,z, w)",
"p(y|do(x))",
"x -> y \n z -> x \n w -> z \n x <-> w \n w <-> y",
control = list(draw_derivation = TRUE)
)
if (requireNamespace("DiagrammeR", quietly = TRUE)) {
plot(out)
}
}
data <- "p(x,y,z)"
query <- "p(y|do(x))"
graph <- "
x -> z
Z -> y
x <-> y
"
x <- dosearch(data, query, graph)
print(x)
data <- "P(x,y,z)"
query <- "P(y|do(x))"
graph <- "
x -> y
z -> x
z -> y
"
x <- dosearch(data, query, graph)
is_identifiable(x)
# TRUE
data <- "P(x,y,z)"
query <- "P(y|do(x))"
graph <- "
x -> y
z -> x
z -> y
"
x <- dosearch(data, query, graph, control = list(formula = FALSE))
get_formula(x, run_again = TRUE)
data <- "P(x,y,z)"
query <- "P(y|do(x))"
graph <- "
x -> y
z -> x
z -> y
"
x <- dosearch(data, query, graph, control = list(draw_derivation = FALSE))
get_derivation(x, run_again = TRUE)
data <- "P(x,y,z)"
query <- "P(y|do(x))"
graph <- "
x -> y
z -> x
z -> y
"
x <- dosearch(data, query, graph, control = list(benchmark = FALSE))
get_benchmark(x, run_again = TRUE)
Run the code above in your browser using DataLab