# Reasoning about experiments (Backdoors and adjustments)

The following example is discussed as Example 3.4 in Chapter 3-4 (http://bayes.cs.ucla.edu/BOOK-2K/ch3-3.pdf). See also http://causality.cs.ucla.edu/blog/index.php/category/back-door-criterion/.

The causal model we are going to study can be represented using the following DAG concerning a set of variables numbered `1`

to `8`

:

```
using CausalInference
using TikzGraphs
# If you have problems with TikzGraphs.jl,
# try alternatively plotting backend GraphRecipes.jl + Plots.jl
# and corresponding plotting function `plot_pc_graph_recipes`
dag = digraph([
1 => 3
3 => 6
2 => 5
5 => 8
6 => 7
7 => 8
1 => 4
2 => 4
4 => 6
4 => 8])
t = plot_pc_graph_tikz(dag)
```

We are interested in the average causal effect (ACE) of a treatment `X`

(variable nr. 6) on an outcome `Y`

(variable nr. 8), which stands for the expected increase of `Y`

per unit of a controlled increase in `X`

. Variables nr. 1 and nr. 2 are unobserved.

*Regressing Y (nr. 8) on X (nr. 6) will fail to measure the effect because of the presence of a confounder C (variable nr. 4)*, which opens a backdoor path, a connection between

`X`

and `Y`

via the path 6 ← 4 → 8 which is not causal. We can avert such problems by checking the backdoor criterion. Indeed

`backdoor_criterion(dag, 6, 8) # false`

reports a problem.

One might want to condition on the confounder `C`

(nr. 4)` to obtain the causal effect, but then

`backdoor_criterion(dag, 6, 8, [4]) # still false`

there is still a problem ( because that conditioning opens up a non-causal path via 6 ← 3 ← 1 → 4 ← 2 → 5 → 8.)

But conditioning on both `Z = [4, 5]`

solves the problem, as verified by the backdoor criterion.

```
backdoor_criterion(dag, 6, 8, [3, 4]) # true
backdoor_criterion(dag, 6, 8, [4, 5]) # true
```

(also conditioning on `Z = [3, 4]`

would be possible.)

Thus, regressing `Y`

on `X`

and controlling for variables numbered `Z = [4, 5]`

we measure the average causal effect.

What we have done by hand here is the search for an backdoor adjustment set. We could have directly queried

`Zs = list_covariate_adjustment(dag, 6, 8, Int[], setdiff(Set(1:8), [1, 2])) # exclude variables nr. 1 and nr. 2 because they are unobserved.`

which lists possible adjustment sets,

`println.(Zs);`

```
Set([4, 3])
Set([5, 4])
Set([5, 4, 3])
```

to get the list of possible adjustment sets. Here `list_backdoor_adjustment`

gives adjustment sets for a backdoor criterion similar to `backdoor_criterion`

and `list_covariate_adjustment`

the more versatile adjustment set based on the sound and complete graphical criterion for covariate adjustment given in [https://arxiv.org/abs/1203.3515] using the algorithmic approach proposed in [https://arxiv.org/abs/1803.00116].