---
title: "Motivation"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Motivation}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
Why another graph package in R? The `caugi` package was designed to provide a _fast_, _flexible_, and _causality-first_ graph interface.
```{r setup}
library(caugi)
```
## Representation of causal graphs
Causal graphs are easy to draw and aid us in understanding causal mechanisms by visual representation. In R, representing them can feel clunky. Historically, users have resorted to adjacency matrices, edge lists, or packages like `igraph` or `graph`.
These tools are great and each have their strengths, but they are not built for _causal_ graphs, which often have special edge types and properties. This leads to situations such as representing undirected edges as two directed edges going in each direction, or representing PAG-type edges by opaque matrix formats, as seen in for example `pcalg`, where
```{r pcalg-pag}
nodes <- c("A", "B", "C", "D", "E")
amat <- matrix(
c(
0L, 2L, 0L, 0L, 1L,
3L, 0L, 2L, 1L, 0L,
0L, 1L, 0L, 0L, 3L,
0L, 1L, 0L, 0L, 3L,
3L, 0L, 3L, 3L, 0L
),
5, 5,
byrow = TRUE, dimnames = list(nodes, nodes)
)
amat
```
represents the graph
```{r caugi-pag, eval=FALSE}
caugi(
A %-->% B %o->% C %---% E,
B %o-o% D %---% E,
A %--o% E
)
```
The second form reads like the picture in your head.
For people working in causal inference and causal discovery, the lack of readable, well supported formats can lead to clunky, hacky code that is hard to read and maintain. `caugi` aims to fix this with a readable syntax, which mimics how we draw graphs by hand, and gives the user the ability to express complex causal relationships.
## Safety
When makeshift solutions are used to represent causal graphs, it leads to not only bugs, but confusion and wasted time. With `caugi` we aim to make causal graphs safe to work with, so you do not accidentally create invalid graphs, and so you can focus on the causal problems at hand, not on the representation.
We have ensured that the `caugi` graph object should be impossible to alter in such a way that the underlying graph class becomes invalid. For example, creating a DAG with `caugi`, acyclicity is guaranteed by construction. Trying to add an edge that would create a cycle will throw an error.
More generally, `caugi` aims to be __graph-class safe__. Think of it as type safety, but on a graph-class level. This safety comes at some costs; if `caugi` doesn't support the graph type you are using, then the graph class should be set to `"UNKNOWN"`, and most operations will not be available, since the interpretation of the relationships described by the graph is _unknown_ to `caugi`. However, this is a small price to pay for safety and clarity. In `caugi`, we prefer clarity over silent misinterpretation. `caugi` will act as your causality guard dog 🐶
We refer to the vignette `vignette("package_use")` to see how to (safely) use `caugi` in your package.
## Performance
Due to the underlying data structure of `caugi`, the graph objects are fast to query, but slower to initialize than other graph object types might be. The trade-off is favorable, as graphs are typically queried many times after being created once. This makes `caugi` suitable for large graphs, where performance matters, but even for small graphs the performance gain is significant to other packages.
You can read more about the performance of `caugi` in `vignette("performance")`.