Skip to content

Commit 95b4ab0

Browse files
Rewrite README, add small things to motivation.rmd, add get_started.rmd and delete introduction.rmd
1 parent a8b1b30 commit 95b4ab0

6 files changed

Lines changed: 186 additions & 288 deletions

File tree

README.Rmd

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,54 +21,82 @@ knitr::opts_chunk$set(
2121
[![extendr](https://img.shields.io/badge/extendr-^0.8.1-276DC2)](https://extendr.github.io/extendr/extendr_api/)
2222
<!-- badges: end -->
2323

24-
> **Causal Graph Interface (for R)** — a fast, tidy toolbox for building, coercing and analysing causal graphs.
24+
> **Causal Graph Interface (for R)** — a blazingly fast, tidy toolbox for building, coercing and analyzing causal graphs.
2525
26-
*caugi* (pronounced **“corgi”**) wraps a high‑performance Rust core in a pipe‑friendly R interface. Convert between many graph formats, compose graphs with expressive infix operators, and run algorithms on large graphs. *caugi* aims to be the go‑to package for causal graphs in R.
26+
```{r}
27+
library(caugi)
28+
```
2729

28-
## Installation
30+
## What is `caugi`?
2931

30-
You can install the development version of caugi from [GitHub](https://github.com/) with:
32+
`caugi` (pronounced "corgi") stands for **Causal Graph Interface**. It is a _causality-first_ graph package that focuses on performance and flexibility. If you are developing scripts or algorithms in the field of causality or if you are learning about causal graphs for the first time, `caugi` is made for you.
3133

32-
```r
33-
# install.packages("pak")
34-
pak::pak("frederikfabriciusbjerre/caugi")
34+
## The basic object: `caugi_graph`
3535

36-
# ... or wait for the first CRAN release
37-
# install.packages("caugi")
38-
```
36+
A `caugi_graph` is the bread and butter of `caugi`. It is easy to create, query, and modify.
3937

40-
## Example
41-
42-
The `caugi` syntax is very close to how you would draw a graph on a whiteboard. Here is a tiny DAG:
43-
```{r example}
44-
library(caugi)
38+
You can create simple graphs as well as a number of predefined graph classes. Currently, we only support `"UNKNOWN"`, `"DAG"`, or `"PDAG"`. We plan on supporting several other causal graph types in future releases, such as `"PAG"`, `"CPDAG"`, `"MAG"`, `"SWIG"`, and `"ADMG"`.
4539

46-
cg <- caugi_graph(A %-->% B + C,
40+
```{r}
41+
# a tiny DAG
42+
cg <- caugi_graph(
43+
A %-->% B + C,
4744
B %-->% D,
4845
C %-->% D,
4946
class = "DAG"
50-
) # optional, guarantees acyclicity by construction
51-
print(cg)
47+
)
5248
```
5349

54-
You can query it:
50+
### Edge operators
51+
52+
The available edges in `caugi` are listed below:
53+
54+
* `%-->%` (directed)
55+
* `%---%` (undirected)
56+
* `%<->%` (bidirected)
57+
* `%o->%` (partially directed)
58+
* `%o--%` (partially undirected)
59+
* `%o-o%` (partial)
60+
61+
You can register more types with `register_caugi_edge()`, if you find that you need a more expressive set of edges. For example, if you want to represent a directed edge in the reverse direction, you can do so like this:
62+
63+
```{r}
64+
register_caugi_edge(
65+
glyph = "<--",
66+
tail_mark = "arrow",
67+
head_mark = "tail",
68+
class = "directed",
69+
symmetric = FALSE
70+
)
71+
72+
caugi_graph(A %-->% B, B %<--% C, class = "DAG")
5573
56-
```{r query}
57-
neighbors(cg, "D")
58-
parents(cg, "D")
59-
children(cg, "A")
60-
ancestors(cg, "D")
61-
descendants(cg, "A")
74+
# reset the registry to default with original edges
75+
reset_caugi_registry()
6276
```
6377

64-
## Key features
78+
We expect this feature to be needing further polishing in future releases, and we would love your input if you use this feature!
79+
80+
## Querying and metrics
81+
82+
`caugi` provides a number of functions to query and analyze `caugi_graph` objects. Some of the available functions are:
83+
* Relational queries, such as `parents()`, `ancestors()`, `neighbors()`, and more.
84+
* Structural queries, such as `is_acyclic()`, `is_cpdag`, and more.
85+
* Graph manipulations, such as `add_edge()`, `remove_node()`, and more.
86+
* Graph metrics, such as `shd()` and `aid()`.
87+
88+
## How it works
89+
90+
`caugi` graphs are represented in a compact Compressed Sparse Row (CSR) format in Rust. `caugi` works with a front-loading philosophy. Since the `caugi` graph is stored in a CSR format, mutations of the graph is computationally expensive compared to other graph storage systems, _but_ it allows for very fast querying. Additionally to the storage format of the graph itself, `caugi` also stores additional information about node relations in such a way that it allows for faster queries without blowing up the object too much.
91+
92+
To accommodate for the cost of mutations, `caugi` graphs are built lazily. This means that when you mutate the graph, for example by adding edges to it, the graph edits are stored in R, but not in Rust. When you then need to query the graphs, the graph will rebuild itself in Rust, and the query will be executed on the newly built graph. You can also use the `build(cg)` function to force building the graph in Rust at any time.
93+
94+
## Why?
95+
It's fast, _dawg_ 🐶 See the [vignette on performance](vignette("performance")) for benchmarks.
96+
97+
## Contribution
98+
Would you like to contribute? Great! Please follow the tidyverse style guide for R code. Before opening a PR, run `styler::style_pkg()` for R and `cargo fmt` for Rust, and make sure to write tests for new features.
99+
65100

66-
| :rocket: | What | Why it matters |
67-
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
68-
| **Flexible coercion & formats** | `as_caugi()` ingests **igraph**, **graphNEL**, **pcalg** `amat` (CPDAG *and* PAG), and sparse or dense (binary/integer‑coded) matrices. | Re‑use existing data structures; no tedious re‑encoding. |
69-
| **PAG & mixed‑graph support** | Native edge codes for PAGs (`o->`, `o-o`, `--o`) and bidirected/undirected edges. | Analyse outputs of discovery algorithms like FCI or RFCI out‑of‑the‑box. |
70-
| **Readable syntax** | `A %-->% B`, `B %<->% C` ... | Write graphs exactly as you draw them on a whiteboard. |
71-
| **Blazing speed** | Core implemented in Rust in a Compressed Sparse Row (CSR) representation. | Millions of edges? No problem. |
72-
| **Frontloading computation** | The CSR format is build to be immutable by design. You can add edges/nodes, but the graph is only rebuilt when you call `build()` or query the graph. | Avoids unnecessary recomputation; keeps your code snappy (and keeps you happy). |
73-
| **S7** | Modern S7 classes and methods. Made to be hard to break by mistake. | Future‑proof, safe, and extensible. |
101+
Did you find an issue? That's paw-ful! Please report an [issue](https://github.com/frederikfabriciusbjerre/caugi/issues)
74102

README.md

Lines changed: 97 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,79 +11,124 @@ coverage](https://codecov.io/gh/frederikfabriciusbjerre/caugi/graph/badge.svg)](
1111
[![extendr](https://img.shields.io/badge/extendr-%5E0.8.1-276DC2)](https://extendr.github.io/extendr/extendr_api/)
1212
<!-- badges: end -->
1313

14-
> **Causal Graph Interface (for R)** — a fast, tidy toolbox for
15-
> building, coercing and analysing causal graphs.
14+
> **Causal Graph Interface (for R)** — a blazingly fast, tidy toolbox
15+
> for building, coercing and analyzing causal graphs.
1616
17-
*caugi* (pronounced **“corgi”**) wraps a high‑performance Rust core in a
18-
pipe‑friendly R interface. Convert between many graph formats, compose
19-
graphs with expressive infix operators, and run algorithms on large
20-
graphs. *caugi* aims to be the go‑to package for causal graphs in R.
17+
``` r
18+
library(caugi)
19+
```
2120

22-
## Installation
21+
## What is `caugi`?
2322

24-
You can install the development version of caugi from
25-
[GitHub](https://github.com/) with:
23+
`caugi` (pronounced “corgi”) stands for **Causal Graph Interface**. It
24+
is a *causality-first* graph package that focuses on performance and
25+
flexibility. If you are developing scripts or algorithms in the field of
26+
causality or if you are learning about causal graphs for the first time,
27+
`caugi` is made for you.
2628

27-
``` r
28-
# install.packages("pak")
29-
pak::pak("frederikfabriciusbjerre/caugi")
29+
## The basic object: `caugi_graph`
3030

31-
# ... or wait for the first CRAN release
32-
# install.packages("caugi")
33-
```
34-
35-
## Example
31+
A `caugi_graph` is the bread and butter of `caugi`. It is easy to
32+
create, query, and modify.
3633

37-
The `caugi` syntax is very close to how you would draw a graph on a
38-
whiteboard. Here is a tiny DAG:
34+
You can create simple graphs as well as a number of predefined graph
35+
classes. Currently, we only support `"UNKNOWN"`, `"DAG"`, or `"PDAG"`.
36+
We plan on supporting several other causal graph types in future
37+
releases, such as `"PAG"`, `"CPDAG"`, `"MAG"`, `"SWIG"`, and `"ADMG"`.
3938

4039
``` r
41-
library(caugi)
42-
43-
cg <- caugi_graph(A %-->% B + C,
40+
# a tiny DAG
41+
cg <- caugi_graph(
42+
A %-->% B + C,
4443
B %-->% D,
4544
C %-->% D,
4645
class = "DAG"
47-
) # optional, guarantees acyclicity by construction
48-
print(cg)
49-
#> # A tibble: 4 × 1
46+
)
47+
```
48+
49+
### Edge operators
50+
51+
The available edges in `caugi` are listed below:
52+
53+
- `%-->%` (directed)
54+
- `%---%` (undirected)
55+
- `%<->%` (bidirected)
56+
- `%o->%` (partially directed)
57+
- `%o--%` (partially undirected)
58+
- `%o-o%` (partial)
59+
60+
You can register more types with `register_caugi_edge()`, if you find
61+
that you need a more expressive set of edges. For example, if you want
62+
to represent a directed edge in the reverse direction, you can do so
63+
like this:
64+
65+
``` r
66+
register_caugi_edge(
67+
glyph = "<--",
68+
tail_mark = "arrow",
69+
head_mark = "tail",
70+
class = "directed",
71+
symmetric = FALSE
72+
)
73+
74+
caugi_graph(A %-->% B, B %<--% C, class = "DAG")
75+
#> # A tibble: 3 × 1
5076
#> name
5177
#> <chr>
5278
#> 1 A
5379
#> 2 B
5480
#> 3 C
55-
#> 4 D
56-
#> # A tibble: 4 × 3
81+
#> # A tibble: 2 × 3
5782
#> from edge to
5883
#> <chr> <chr> <chr>
5984
#> 1 A --> B
60-
#> 2 A --> C
61-
#> 3 B --> D
62-
#> 4 C --> D
85+
#> 2 B <-- C
86+
87+
# reset the registry to default with original edges
88+
reset_caugi_registry()
6389
```
6490

65-
You can query it:
91+
We expect this feature to be needing further polishing in future
92+
releases, and we would love your input if you use this feature!
6693

67-
``` r
68-
neighbors(cg, "D")
69-
#> [1] "B" "C"
70-
parents(cg, "D")
71-
#> [1] "B" "C"
72-
children(cg, "A")
73-
#> [1] "B" "C"
74-
ancestors(cg, "D")
75-
#> [1] "A" "B" "C"
76-
descendants(cg, "A")
77-
#> [1] "B" "C" "D"
78-
```
94+
## Querying and metrics
95+
96+
`caugi` provides a number of functions to query and analyze
97+
`caugi_graph` objects. Some of the available functions are: \*
98+
Relational queries, such as `parents()`, `ancestors()`, `neighbors()`,
99+
and more. \* Structural queries, such as `is_acyclic()`, `is_cpdag`, and
100+
more. \* Graph manipulations, such as `add_edge()`, `remove_node()`, and
101+
more. \* Graph metrics, such as `shd()` and `aid()`.
102+
103+
## How it works
104+
105+
`caugi` graphs are represented in a compact Compressed Sparse Row (CSR)
106+
format in Rust. `caugi` works with a front-loading philosophy. Since the
107+
`caugi` graph is stored in a CSR format, mutations of the graph is
108+
computationally expensive compared to other graph storage systems, *but*
109+
it allows for very fast querying. Additionally to the storage format of
110+
the graph itself, `caugi` also stores additional information about node
111+
relations in such a way that it allows for faster queries without
112+
blowing up the object too much.
113+
114+
To accommodate for the cost of mutations, `caugi` graphs are built
115+
lazily. This means that when you mutate the graph, for example by adding
116+
edges to it, the graph edits are stored in R, but not in Rust. When you
117+
then need to query the graphs, the graph will rebuild itself in Rust,
118+
and the query will be executed on the newly built graph. You can also
119+
use the `build(cg)` function to force building the graph in Rust at any
120+
time.
121+
122+
## Why?
123+
124+
It’s fast, *dawg* 🐶 See the [vignette on
125+
performance](vignette(%22performance%22)) for benchmarks.
126+
127+
## Contribution
79128

80-
## Key features
129+
Would you like to contribute? Great! Please follow the tidyverse style
130+
guide for R code. Before opening a PR, run `styler::style_pkg()` for R
131+
and `cargo fmt` for Rust, and make sure to write tests for new features.
81132

82-
| :rocket: | What | Why it matters |
83-
|----|----|----|
84-
| **Flexible coercion & formats** | `as_caugi()` ingests **igraph**, **graphNEL**, **pcalg** `amat` (CPDAG *and* PAG), and sparse or dense (binary/integer‑coded) matrices. | Re‑use existing data structures; no tedious re‑encoding. |
85-
| **PAG & mixed‑graph support** | Native edge codes for PAGs (`o->`, `o-o`, `--o`) and bidirected/undirected edges. | Analyse outputs of discovery algorithms like FCI or RFCI out‑of‑the‑box. |
86-
| **Readable syntax** | `A %-->% B`, `B %<->% C`| Write graphs exactly as you draw them on a whiteboard. |
87-
| **Blazing speed** | Core implemented in Rust in a Compressed Sparse Row (CSR) representation. | Millions of edges? No problem. |
88-
| **Frontloading computation** | The CSR format is build to be immutable by design. You can add edges/nodes, but the graph is only rebuilt when you call `build()` or query the graph. | Avoids unnecessary recomputation; keeps your code snappy (and keeps you happy). |
89-
| **S7** | Modern S7 classes and methods. Made to be hard to break by mistake. | Future‑proof, safe, and extensible. |
133+
Did you find an issue? That’s paw-ful! Please report an
134+
[issue](https://github.com/frederikfabriciusbjerre/caugi/issues)

0 commit comments

Comments
 (0)