---
title: "Getting Started"
output: 
  rmarkdown::html_vignette:
    md_extensions: [ 
      "-autolink_bare_uris" 
    ]
vignette: >
  %\VignetteIndexEntry{Getting Started}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

```

```{r setup, message = FALSE, warning = FALSE}
if(!requireNamespace("fabricatr", quietly = TRUE)) {
  install.packages("fabricatr")
}

library(CausalQueries)
library(dplyr)
library(knitr)
```

# Make a model

**Generating**: To make a model you need to provide a DAG statement to `make_model`.  
For instance 

* `"X->Y"`
*  `"X -> M -> Y <- X"` or  
* `"Z -> X -> Y <-> X"`. 

```{r}
# examples of models
xy_model <- make_model("X -> Y")
iv_model <- make_model("Z -> X -> Y <-> X")

```

**Graphing**: Once you have made a model you can inspect the DAG:

```{r}
plot(xy_model)
```

**Simple summaries:** You can access a simple summary using `summary()`


```{r}
summary(xy_model)
```

or you can examine model details using `inspect()`.

**Inspecting**: The model has a set of parameters and a default distribution over these.


```{r}
xy_model |> inspect("parameters_df") 
```

**Tailoring**: These features can be edited using `set_restrictions`, `set_priors` and `set_parameters`.

Here is an example of setting a monotonicity restriction  (see `?set_restrictions` for more): 

```{r}
iv_model <- 
  iv_model |> set_restrictions(decreasing('Z', 'X'))
```

Here is an example of setting priors (see `?set_priors` for more): 

```{r}
iv_model <- 
  iv_model |> set_priors(distribution = "jeffreys")
```

**Simulation**: Data can be drawn from a model like this:

```{r}
data <- make_data(iv_model, n = 4) 

data |> kable()

```

# Update the model

**Updating**: Update using `update_model`. You can pass all `rstan` arguments to `update_model`.

```{r}
df <- 
  data.frame(X = rbinom(100, 1, .5)) |>
  mutate(Y = rbinom(100, 1, .25 + X*.5))

xy_model <- 
  xy_model |> 
  update_model(df, refresh = 0)
```

**Inspecting**: You can access the posterior distribution on model parameters directly thus:

```{r}

xy_model |> grab("posterior_distribution") |> 
  head() |> kable()

```

where each row is a draw of parameters.

# Query the model

## Arbitrary queries

**Querying**: You ask arbitrary causal queries of the model. 

Examples of *unconditional* queries:

```{r}
xy_model |> 
  query_model("Y[X=1] > Y[X=0]", using = c("priors", "posteriors")) 
```

Examples of *conditional* queries:

```{r}
xy_model |> 
  query_model("Y[X=1] > Y[X=0]", using = c("priors", "posteriors"),
              given = "X==1 & Y == 1") 
```

Queries can even be conditional on counterfactual quantities. Here the probability of a positive effect given *some* effect:

```{r}
xy_model |> 
  query_model("Y[X=1] > Y[X=0]", using = c("priors", "posteriors"),
              given = "Y[X=1] != Y[X=0]") 
```

## Output

Query output is ready for printing as tables, but can also be plotted, which is especially useful with batch requests:


```{r, fig.height = 4, fig.width = 8}
batch_queries <- xy_model |> 
  query_model(queries = c("Y[X=1] - Y[X=0]", "Y[X=1] > Y[X=0]"), 
              using = c("priors", "posteriors"), 
              given = c(TRUE, "Y[X=1] != Y[X=0]"),
              expand_grid = TRUE) 

batch_queries |> kable(digits = 2, caption = "tabular output")
batch_queries |> plot() 
```
