Title: | Graph Adjustment Identification Distances for Causal Graphs |
Version: | 0.1.0 |
Description: | Make efficient Rust implementations of graph adjustment identification distances available in R. These distances (based on ancestor, optimal, and parent adjustment) count how often the respective adjustment identification strategy leads to causal inferences that are incorrect relative to a ground-truth graph when applied to a candidate graph instead. See also Henckel, Würtzen, Weichwald (2024) <doi:10.48550/arXiv.2402.08616>. |
License: | MPL version 1.0 | MPL version 1.1 | MPL version 2.0 [expanded from: MPL] |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.2 |
Config/rextendr/version: | 0.4.1 |
SystemRequirements: | Cargo (Rust's package manager), rustc |
Depends: | R (≥ 4.2) |
Suggests: | testthat (≥ 3.0.0) |
Config/testthat/edition: | 3 |
URL: | https://github.com/CausalDisco/gadjid |
BugReports: | https://github.com/CausalDisco/gadjid/issues |
NeedsCompilation: | yes |
Packaged: | 2025-08-25 08:44:52 UTC; qbr527 |
Author: | Sebastian Weichwald [aut, cph, cre], Theo Würtzen [aut], Leonard Henckel [aut], Authors of the dependency Rust crates [ctb] (see inst/AUTHORS file for details) |
Maintainer: | Sebastian Weichwald <sweichwald@math.ku.dk> |
Repository: | CRAN |
Date/Publication: | 2025-08-29 11:00:08 UTC |
Ancestor Adjustment Identification Distance between two DAG / CPDAG adjacency matrices
Description
Computes the ancestor adjustment intervention distance between the true g_true
DAG or CPDAG and an estimated g_guess
DAG or CPDAG.
Usage
ancestor_aid(g_true, g_guess, edge_direction)
Arguments
g_true |
Adjacency matrix of the true graph |
g_guess |
Adjacency matrix of the guess graph |
edge_direction |
either "from row to column" or "from column to row" |
Details
For details see Henckel, Würtzen, Weichwald (2024) doi:10.48550/arXiv.2402.08616
The source code is available at github.com/CausalDisco/gadjid
Graph inputs are accepted as adjacency matrices of type double. An adjacency matrix for a DAG may only contain 0s and 1s. An adjacency matrix for a CPDAG may only contain 0s, 1s and 2s. DAG and CPDAG inputs are validated for acyclicity. However, for CPDAG inputs, the user needs to ensure the adjacency matrix indeed codes a valid CPDAG (instead of just a PDAG).
If edge_direction="from row to column"
, then
a 1
in row r
and column c
codes a directed edge ‘r → c’;
if edge_direction="from column to row"
, then
a 1
in row r
and column c
codes a directed edge ‘c → r’;
for either setting of edge_direction
,
a 2
in row r
and column c
codes an undirected edge ‘r – c’
(an additional 2
in row c
and column r
is ignored;
one of the two entries is sufficient to code an undirected edge).
Value
2-element vector of type double
c(normalized error in [0,1], total number of errors)
References
L Henckel, T Würtzen, S Weichwald. "Adjustment Identification Distance: A gadjid for Causal Structure Learning." Proceedings of the 40th Conference on Uncertainty in Artificial Intelligence (UAI), 2024. doi:10.48550/arXiv.2402.08616
Examples
full <- rbind(c(0, 1, 1, 1),
c(0, 0, 1, 1),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
chain <- rbind(c(0, 1, 0, 0),
c(0, 0, 1, 0),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
identical(ancestor_aid(full, chain, "from row to column"), c(0/12, 0))
Optimal Adjustment Identification Distance between two DAG / CPDAG adjacency matrices
Description
Computes the optimal adjustment intervention distance between the true g_true
DAG or CPDAG and an estimated g_guess
DAG or CPDAG.
Usage
oset_aid(g_true, g_guess, edge_direction)
Arguments
g_true |
Adjacency matrix of the true graph |
g_guess |
Adjacency matrix of the guess graph |
edge_direction |
either "from row to column" or "from column to row" |
Details
For details see Henckel, Würtzen, Weichwald (2024) doi:10.48550/arXiv.2402.08616
The source code is available at github.com/CausalDisco/gadjid
Graph inputs are accepted as adjacency matrices of type double. An adjacency matrix for a DAG may only contain 0s and 1s. An adjacency matrix for a CPDAG may only contain 0s, 1s and 2s. DAG and CPDAG inputs are validated for acyclicity. However, for CPDAG inputs, the user needs to ensure the adjacency matrix indeed codes a valid CPDAG (instead of just a PDAG).
If edge_direction="from row to column"
, then
a 1
in row r
and column c
codes a directed edge ‘r → c’;
if edge_direction="from column to row"
, then
a 1
in row r
and column c
codes a directed edge ‘c → r’;
for either setting of edge_direction
,
a 2
in row r
and column c
codes an undirected edge ‘r – c’
(an additional 2
in row c
and column r
is ignored;
one of the two entries is sufficient to code an undirected edge).
Value
2-element vector of type double
c(normalized error in [0,1], total number of errors)
References
L Henckel, T Würtzen, S Weichwald. "Adjustment Identification Distance: A gadjid for Causal Structure Learning." Proceedings of the 40th Conference on Uncertainty in Artificial Intelligence (UAI), 2024. doi:10.48550/arXiv.2402.08616
Examples
full <- rbind(c(0, 1, 1, 1),
c(0, 0, 1, 1),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
chain <- rbind(c(0, 1, 0, 0),
c(0, 0, 1, 0),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
identical(oset_aid(full, chain, "from row to column"), c(3/12, 3))
Parent Adjustment Identification Distance between two DAG / CPDAG adjacency matrices
Description
Computes the parent adjustment intervention distance between the true g_true
DAG or CPDAG and an estimated g_guess
DAG or CPDAG.
Usage
parent_aid(g_true, g_guess, edge_direction)
Arguments
g_true |
Adjacency matrix of the true graph |
g_guess |
Adjacency matrix of the guess graph |
edge_direction |
either "from row to column" or "from column to row" |
Details
For details see Henckel, Würtzen, Weichwald (2024) doi:10.48550/arXiv.2402.08616
The source code is available at github.com/CausalDisco/gadjid
Graph inputs are accepted as adjacency matrices of type double. An adjacency matrix for a DAG may only contain 0s and 1s. An adjacency matrix for a CPDAG may only contain 0s, 1s and 2s. DAG and CPDAG inputs are validated for acyclicity. However, for CPDAG inputs, the user needs to ensure the adjacency matrix indeed codes a valid CPDAG (instead of just a PDAG).
If edge_direction="from row to column"
, then
a 1
in row r
and column c
codes a directed edge ‘r → c’;
if edge_direction="from column to row"
, then
a 1
in row r
and column c
codes a directed edge ‘c → r’;
for either setting of edge_direction
,
a 2
in row r
and column c
codes an undirected edge ‘r – c’
(an additional 2
in row c
and column r
is ignored;
one of the two entries is sufficient to code an undirected edge).
Value
2-element vector of type double
c(normalized error in [0,1], total number of errors)
References
L Henckel, T Würtzen, S Weichwald. "Adjustment Identification Distance: A gadjid for Causal Structure Learning." Proceedings of the 40th Conference on Uncertainty in Artificial Intelligence (UAI), 2024. doi:10.48550/arXiv.2402.08616
Examples
full <- rbind(c(0, 1, 1, 1),
c(0, 0, 1, 1),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
chain <- rbind(c(0, 1, 0, 0),
c(0, 0, 1, 0),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
identical(parent_aid(full, chain, "from row to column"), c(4/12, 4))
Structural Hamming Distance between two DAG / CPDAG adjacency matrices
Description
Computes the structural Hamming distance between the true g_true
PDAG and an estimated g_guess
PDAG.
Usage
shd(g_true, g_guess)
Arguments
g_true |
Adjacency matrix of the true partially directed acyclic graph |
g_guess |
Adjacency matrix of the guess partially directed acyclic graph |
Details
For details see Henckel, Würtzen, Weichwald (2024) doi:10.48550/arXiv.2402.08616
The source code is available at github.com/CausalDisco/gadjid
Graph inputs are accepted as adjacency matrices of type double. An adjacency matrix for a PDAG may only contain 0s, 1s and 2s. PDAG are validated for acyclicity.
A 1
in row r
and column c
codes a directed edge and
a 1
in row c
and column r
codes a directed edge in reverse direction;
a 2
in row r
and column c
codes an undirected edge ‘r – c’
(an additional 2
in row c
and column r
is ignored;
one of the two entries is sufficient to code an undirected edge).
Value
2-element vector of type double
c(normalized error in [0,1], total number of errors)
Examples
full <- rbind(c(0, 1, 1, 1),
c(0, 0, 1, 1),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
chain <- rbind(c(0, 1, 0, 0),
c(0, 0, 1, 0),
c(0, 0, 0, 1),
c(0, 0, 0, 0))
identical(shd(full, chain), c(3/6, 3))
Structural Identification Distance between two DAG adjacency matrices
Description
Computes the structural intervention distance (SID),
between the true g_true
DAG and an estimated g_guess
DAG.
Usage
sid(g_true, g_guess, edge_direction)
Arguments
g_true |
Adjacency matrix of the true directed acyclic graph |
g_guess |
Adjacency matrix of the guess directed acyclic graph |
edge_direction |
either "from row to column" or "from column to row" |
Details
Since the Parent-AID reduces to the SID in the special case of DAG inputs and is efficiently implemented using reachability algorithms, it offers a faster way to calculate the SID; see also Henckel, Würtzen, Weichwald (2024) doi:10.48550/arXiv.2402.08616. The example below can be compared to
library("SID") system.time(structIntervDist(random_dag(20), random_dag(20)))
For details see Henckel, Würtzen, Weichwald (2024) doi:10.48550/arXiv.2402.08616
The source code is available at github.com/CausalDisco/gadjid
Graph inputs are accepted as adjacency matrices of type double. An adjacency matrix for a DAG may only contain 0s and 1s. DAG inputs are validated for acyclicity.
If edge_direction="from row to column"
, then
a 1
in row r
and column c
codes a directed edge ‘r → c’;
if edge_direction="from column to row"
, then
a 1
in row r
and column c
codes a directed edge ‘c → r’.
Value
2-element vector of type double
c(normalized error in [0,1], total number of errors)
References
L Henckel, T Würtzen, S Weichwald. "Adjustment Identification Distance: A gadjid for Causal Structure Learning." Proceedings of the 40th Conference on Uncertainty in Artificial Intelligence (UAI), 2024. doi:10.48550/arXiv.2402.08616
J Peters,P Bühlmann. "Structural intervention distance for evaluating causal graphs." Neural Compututation 27(3), 771–799, 2015. doi:10.1162/NECO_a_00708
Examples
random_dag <- function(n, p=0.1) {
P <- sample(n)
m <- matrix(0, n, n)
m[upper.tri(m)] <- rbinom(n*(n-1)/2, 1, p)
m[P, P]
}
system.time(sid(random_dag(400), random_dag(400), "from row to column"))