| Title: | Causal Graph Interface |
|---|---|
| Description: | Create, query, and modify causal graphs. 'caugi' (Causal Graph Interface) is a causality-first, high performance graph package that provides a simple interface to build, structure, and examine causal relationships. |
| Authors: | Frederik Fabricius-Bjerre [aut, cre, cph], Johan Larsson [aut] (ORCID: <https://orcid.org/0000-0002-4029-5945>), Michael Sachs [aut] (ORCID: <https://orcid.org/0000-0002-1279-8676>), Bjarke Hautop Kristensen [aut] |
| Maintainer: | Frederik Fabricius-Bjerre <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.2.0.9000 |
| Built: | 2026-06-08 20:28:33 UTC |
| Source: | https://github.com/frederikfabriciusbjerre/caugi |
Arrange two plots side-by-side with configurable spacing. The + and |
operators are equivalent and can be used interchangeably. Compositions can
be nested to create complex multi-plot layouts.
e1 |
A |
e2 |
A |
The spacing between plots is controlled by the global option
caugi_options()$plot$spacing, which defaults to grid::unit(1, "lines").
Compositions can be nested arbitrarily:
p1 + p2 - two plots side-by-side
(p1 + p2) + p3 - three plots in a row
(p1 + p2) / p3 - two plots on top, one below
A caugi_plot object containing the composed layout
caugi_options() for configuring spacing and default styles
Other plotting:
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
cg1 <- caugi(A %-->% B, B %-->% C) cg2 <- caugi(X %-->% Y, Y %-->% Z) p1 <- plot(cg1, main = "Graph 1") p2 <- plot(cg2, main = "Graph 2") # Horizontal composition p1 + p2 p1 | p2 # equivalent # Adjust spacing caugi_options(plot = list(spacing = grid::unit(2, "lines"))) p1 + p2cg1 <- caugi(A %-->% B, B %-->% C) cg2 <- caugi(X %-->% Y, Y %-->% Z) p1 <- plot(cg1, main = "Graph 1") p2 <- plot(cg2, main = "Graph 2") # Horizontal composition p1 + p2 p1 | p2 # equivalent # Adjust spacing caugi_options(plot = list(spacing = grid::unit(2, "lines"))) p1 + p2
Computes an adjustment set for X -> Y in a DAG.
adjustment_set( cg, X = NULL, Y = NULL, X_index = NULL, Y_index = NULL, type = c("optimal", "parents", "backdoor") )adjustment_set( cg, X = NULL, Y = NULL, X_index = NULL, Y_index = NULL, type = c("optimal", "parents", "backdoor") )
cg |
A |
X, Y
|
Node names. |
X_index, Y_index
|
Optional numeric 1-based indices. |
type |
One of |
Types supported:
"parents": minus
"backdoor": Pearl backdoor formula
"optimal": O-set (only for single x and single y)
A character vector of node names representing the adjustment set.
Other adjustment:
all_adjustment_sets_admg(),
all_backdoor_sets(),
d_separated(),
is_valid_adjustment_admg(),
is_valid_backdoor(),
minimal_separator()
cg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) adjustment_set(cg, "X", "Y", type = "parents") # C, A adjustment_set(cg, "X", "Y", type = "backdoor") # C, A adjustment_set(cg, "X", "Y", type = "optimal") # Kcg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) adjustment_set(cg, "X", "Y", type = "parents") # C, A adjustment_set(cg, "X", "Y", type = "backdoor") # C, A adjustment_set(cg, "X", "Y", type = "optimal") # K
Compute the Adjustment Identification Distance (AID) between two
graphs using the gadjid Rust package.
aid(truth, guess, type = c("oset", "ancestor", "parent"), normalized = TRUE)aid(truth, guess, type = c("oset", "ancestor", "parent"), normalized = TRUE)
truth |
A |
guess |
A |
type |
A character string specifying the type of AID to compute.
Options are |
normalized |
Logical; if |
A numeric representing the AID between the two graphs, if
normalized = TRUE, or an integer count if normalized = FALSE.
set.seed(1) truth <- generate_graph(n = 100, m = 200, class = "DAG") guess <- generate_graph(n = 100, m = 200, class = "DAG") aid(truth, guess) # 0.0187set.seed(1) truth <- generate_graph(n = 100, m = 200, class = "DAG") guess <- generate_graph(n = 100, m = 200, class = "DAG") aid(truth, guess) # 0.0187
Enumerates all valid adjustment sets for estimating the causal
effect of X on Y in an ADMG, up to a specified maximum size.
all_adjustment_sets_admg( cg, X = NULL, Y = NULL, X_index = NULL, Y_index = NULL, minimal = TRUE, max_size = 3L )all_adjustment_sets_admg( cg, X = NULL, Y = NULL, X_index = NULL, Y_index = NULL, minimal = TRUE, max_size = 3L )
cg |
A |
X, Y
|
Node names (can be vectors for multiple treatments/outcomes). |
X_index, Y_index
|
Optional 1-based indices. |
minimal |
Logical; if |
max_size |
Integer; maximum size of sets to consider (default 3). |
A list of character vectors, each a valid adjustment set (possibly empty list if none exist).
Other adjustment:
adjustment_set(),
all_backdoor_sets(),
d_separated(),
is_valid_adjustment_admg(),
is_valid_backdoor(),
minimal_separator()
cg <- caugi( L %-->% X, X %-->% Y, L %-->% Y, M %-->% Y, class = "ADMG" ) all_adjustment_sets_admg(cg, X = "X", Y = "Y", minimal = TRUE) # Returns {L} as minimal adjustment setcg <- caugi( L %-->% X, X %-->% Y, L %-->% Y, M %-->% Y, class = "ADMG" ) all_adjustment_sets_admg(cg, X = "X", Y = "Y", minimal = TRUE) # Returns {L} as minimal adjustment set
This function returns the backdoor sets up to size max_size,
which per default is set to 10.
all_backdoor_sets( cg, X = NULL, Y = NULL, X_index = NULL, Y_index = NULL, minimal = TRUE, max_size = 3L )all_backdoor_sets( cg, X = NULL, Y = NULL, X_index = NULL, Y_index = NULL, minimal = TRUE, max_size = 3L )
cg |
A |
X, Y
|
Single node name. |
X_index, Y_index
|
Optional 1-based indices (exclusive with name args). |
minimal |
Logical; if |
max_size |
Integer; maximum size of sets to consider (default 3). |
A list of character vectors, each an adjustment set (possibly empty).
Other adjustment:
adjustment_set(),
all_adjustment_sets_admg(),
d_separated(),
is_valid_adjustment_admg(),
is_valid_backdoor(),
minimal_separator()
cg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) all_backdoor_sets(cg, X = "X", Y = "Y", max_size = 3L, minimal = FALSE) #> [[1]] #> [1] "A" #> #> [[2]] #> [1] "K" #> #> [[3]] #> [1] "C" "A" #> #> [[4]] #> [1] "C" "K" #> #> [[5]] #> [1] "A" "K" #> #> [[6]] #> [1] "C" "A" "K" all_backdoor_sets(cg, X = "X", Y = "Y", max_size = 3L, minimal = TRUE) #> [[1]] #> [1] "A" #> #> [[2]] #> [1] "K"cg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) all_backdoor_sets(cg, X = "X", Y = "Y", max_size = 3L, minimal = FALSE) #> [[1]] #> [1] "A" #> #> [[2]] #> [1] "K" #> #> [[3]] #> [1] "C" "A" #> #> [[4]] #> [1] "C" "K" #> #> [[5]] #> [1] "A" "K" #> #> [[6]] #> [1] "C" "A" "K" all_backdoor_sets(cg, X = "X", Y = "Y", max_size = 3L, minimal = TRUE) #> [[1]] #> [1] "A" #> #> [[2]] #> [1] "K"
caugi
Get ancestors of nodes in a caugi
ancestors( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )ancestors( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
open |
Boolean. Determines how the graph is interpreted when retrieving ancestors.
Default is taken from |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) ancestors(cg, "A") # NULL ancestors(cg, "A", open = FALSE) # A ancestors(cg, index = 2) # "A" ancestors(cg, "B") # "A" ancestors(cg, c("B", "C")) #> $B #> [1] "A" #> #> $C #> [1] "A" "B"cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) ancestors(cg, "A") # NULL ancestors(cg, "A", open = FALSE) # A ancestors(cg, index = 2) # "A" ancestors(cg, "B") # "A" ancestors(cg, c("B", "C")) #> $B #> [1] "A" #> #> $C #> [1] "A" "B"
caugi
Get the anterior set of nodes in a graph. The anterior set (Richardson and Spirtes, 2002) includes all nodes reachable by following paths where every edge is either undirected or directed toward the target node.
For DAGs, the anterior set equals the ancestor set (since there are no undirected edges). For PDAGs, it includes both ancestors and nodes reachable via undirected edges.
anteriors( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )anteriors( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
open |
Boolean. Determines how the graph is interpreted when retrieving anteriors.
Default is taken from |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Richardson, T. and Spirtes, P. (2002). Ancestral graph Markov models. The Annals of Statistics, 30(4):962-1030.
Other queries:
ancestors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
# PDAG example with directed and undirected edges cg <- caugi( A %-->% B %---% C, B %-->% D, class = "PDAG" ) anteriors(cg, "A") # NULL (no anteriors) anteriors(cg, "A", open = FALSE) # A anteriors(cg, "C") # A, B anteriors(cg, "D") # A, B, C # For DAGs, anteriors equals ancestors cg_dag <- caugi( A %-->% B %-->% C, class = "DAG" ) anteriors(cg_dag, "C") # A, B# PDAG example with directed and undirected edges cg <- caugi( A %-->% B %---% C, B %-->% D, class = "PDAG" ) anteriors(cg, "A") # NULL (no anteriors) anteriors(cg, "A", open = FALSE) # A anteriors(cg, "C") # A, B anteriors(cg, "D") # A, B, C # For DAGs, anteriors equals ancestors cg_dag <- caugi( A %-->% B %-->% C, class = "DAG" ) anteriors(cg_dag, "C") # A, B
Does not take other edge types than the one found in a PDAG.
as_adjacency(x)as_adjacency(x)
x |
A |
An integer 0/1 adjacency matrix with row/col names.
Other conversions:
as_bnlearn(),
as_caugi(),
as_dagitty(),
as_igraph()
cg <- caugi( A %-->% B, class = "DAG" ) adj <- as_adjacency(cg)cg <- caugi( A %-->% B, class = "DAG" ) adj <- as_adjacency(cg)
Convert a caugi to a bnlearn network
as_bnlearn(x)as_bnlearn(x)
x |
A |
A bnlearn DAG.
Other conversions:
as_adjacency(),
as_caugi(),
as_dagitty(),
as_igraph()
cg <- caugi( A %-->% B, class = "DAG" ) g_bn <- as_bnlearn(cg)cg <- caugi( A %-->% B, class = "DAG" ) g_bn <- as_bnlearn(cg)
caugi
Convert an object to a caugi. The object can be a
graphNEL, matrix, tidygraph, daggity, bn, or igraph.
as_caugi( x, class = c("DAG", "UG", "PDAG", "MPDAG", "ADMG", "AG", "PAG", "UNKNOWN"), simple = TRUE, collapse = FALSE, collapse_to = "---", ... )as_caugi( x, class = c("DAG", "UG", "PDAG", "MPDAG", "ADMG", "AG", "PAG", "UNKNOWN"), simple = TRUE, collapse = FALSE, collapse_to = "---", ... )
x |
An object to convert to a |
class |
Character; one of |
simple |
logical. If |
collapse |
logical. If |
collapse_to |
Character string to use as the edge glyph when collapsing.
Should be a registered symmetrical edge glyph. Default is |
... |
Additional arguments passed to specific methods. |
For matrices, as_caugi assumes that the rows are the from nodes
and the columns are the to nodes. Thus, for a graph, G: A –> B, we would
have that G["A", "B"] == 1 and G["B", "A"] == 0.
For PAGs, the integer codes are as follows (as used in pcalg):
0: no edge
1: circle (e.g., A o-o B or A --o B)
2: arrowhead (e.g., A --> B or A o-> B)
3: tail (e.g., A --o B or A --- B)
A caugi object.
Other conversions:
as_adjacency(),
as_bnlearn(),
as_dagitty(),
as_igraph()
# igraph ig <- igraph::graph_from_literal(A - +B, B - +C) cg_ig <- as_caugi(ig, class = "DAG") # graphNEL gn <- graph::graphNEL(nodes = c("A", "B", "C"), edgemode = "directed") gn <- graph::addEdge("A", "B", gn) gn <- graph::addEdge("B", "C", gn) cg_gn <- as_caugi(gn, class = "DAG") # adjacency matrix m <- matrix(0L, 3, 3, dimnames = list(LETTERS[1:3], LETTERS[1:3])) m["A", "B"] <- 1L m["B", "C"] <- 1L cg_adj <- as_caugi(m, class = "DAG") # bnlearn bn <- bnlearn::model2network("[A][B|A][C|B]") cg_bn <- as_caugi(bn, class = "DAG") # dagitty dg <- dagitty::dagitty("dag { A -> B B -> C }") cg_dg <- as_caugi(dg, class = "DAG") cg <- caugi(A %-->% B %-->% C, class = "DAG") # check that all nodes are equal in all graph objects for (cg_converted in list(cg_ig, cg_gn, cg_adj, cg_bn, cg_dg)) { stopifnot(identical(nodes(cg), nodes(cg_converted))) stopifnot(identical(edges(cg), edges(cg_converted))) } # collapse mutual edges ig2 <- igraph::graph_from_literal(A - +B, B - +A, C - +D) cg2 <- as_caugi(ig2, class = "PDAG", collapse = TRUE, collapse_to = "---") # coded integer matrix for PAGs (pcalg style) nm <- c("A", "B", "C", "D") M <- matrix(0L, 4, 4, dimnames = list(nm, nm)) # A --> B M["A", "B"] <- 2L # mark at B end M["B", "A"] <- 3L # mark at A end # A --- C M["A", "C"] <- 3L M["C", "A"] <- 3L # B o-> C M["B", "C"] <- 2L M["C", "B"] <- 1L # C o-o D M["C", "D"] <- 1L M["D", "C"] <- 1L cg <- as_caugi(M, class = "PAG")# igraph ig <- igraph::graph_from_literal(A - +B, B - +C) cg_ig <- as_caugi(ig, class = "DAG") # graphNEL gn <- graph::graphNEL(nodes = c("A", "B", "C"), edgemode = "directed") gn <- graph::addEdge("A", "B", gn) gn <- graph::addEdge("B", "C", gn) cg_gn <- as_caugi(gn, class = "DAG") # adjacency matrix m <- matrix(0L, 3, 3, dimnames = list(LETTERS[1:3], LETTERS[1:3])) m["A", "B"] <- 1L m["B", "C"] <- 1L cg_adj <- as_caugi(m, class = "DAG") # bnlearn bn <- bnlearn::model2network("[A][B|A][C|B]") cg_bn <- as_caugi(bn, class = "DAG") # dagitty dg <- dagitty::dagitty("dag { A -> B B -> C }") cg_dg <- as_caugi(dg, class = "DAG") cg <- caugi(A %-->% B %-->% C, class = "DAG") # check that all nodes are equal in all graph objects for (cg_converted in list(cg_ig, cg_gn, cg_adj, cg_bn, cg_dg)) { stopifnot(identical(nodes(cg), nodes(cg_converted))) stopifnot(identical(edges(cg), edges(cg_converted))) } # collapse mutual edges ig2 <- igraph::graph_from_literal(A - +B, B - +A, C - +D) cg2 <- as_caugi(ig2, class = "PDAG", collapse = TRUE, collapse_to = "---") # coded integer matrix for PAGs (pcalg style) nm <- c("A", "B", "C", "D") M <- matrix(0L, 4, 4, dimnames = list(nm, nm)) # A --> B M["A", "B"] <- 2L # mark at B end M["B", "A"] <- 3L # mark at A end # A --- C M["A", "C"] <- 3L M["C", "A"] <- 3L # B o-> C M["B", "C"] <- 2L M["C", "B"] <- 1L # C o-o D M["C", "D"] <- 1L M["D", "C"] <- 1L cg <- as_caugi(M, class = "PAG")
Convert a caugi to a dagitty graph
as_dagitty(x)as_dagitty(x)
x |
A |
A dagitty object.
Other conversions:
as_adjacency(),
as_bnlearn(),
as_caugi(),
as_igraph()
cg <- caugi( A %-->% B, class = "DAG" ) g_dg <- as_dagitty(cg)cg <- caugi( A %-->% B, class = "DAG" ) g_dg <- as_dagitty(cg)
Convert a caugi to an igraph object
as_igraph(x, ...)as_igraph(x, ...)
x |
A |
... |
Additional arguments passed to |
An igraph object representing the same graph structure.
Other conversions:
as_adjacency(),
as_bnlearn(),
as_caugi(),
as_dagitty()
cg <- caugi( A %-->% B, class = "DAG" ) ig <- as_igraph(cg)cg <- caugi( A %-->% B, class = "DAG" ) ig <- as_igraph(cg)
caugi graphForces lazy compilation of the caugi graph
without running a specific query. Useful to pre-initialize the graph.
build(cg)build(cg)
cg |
A |
The input caugi object (invisibly), with its graph built.
Other verbs:
caugi_verbs
cg <- caugi(A %-->% B, class = "DAG") build(cg) # initialize graph without queryingcg <- caugi(A %-->% B, class = "DAG") build(cg) # initialize graph without querying
caugi from edge expressions.Create a caugi from a series of edge expressions using
infix operators. Nodes can be specified as symbols, strings, or numbers.
The following edge operators are supported by default:
%-->% for directed edges (A –> B)
%---% for undirected edges (A — B)
%<->% for bidirected edges (A <-> B)
%o->% for partially directed edges (A o-> B)
%--o% for partially undirected edges (A –o B)
%o-o% for partial edges (A o-o B)
You can register additional edge types using register_caugi_edge().
caugi( ..., from = NULL, edge = NULL, to = NULL, nodes = NULL, edges_df = NULL, simple = TRUE, build = NULL, class = c("AUTO", "DAG", "UG", "PDAG", "MPDAG", "ADMG", "AG", "UNKNOWN"), state = NULL, .session = NULL )caugi( ..., from = NULL, edge = NULL, to = NULL, nodes = NULL, edges_df = NULL, simple = TRUE, build = NULL, class = c("AUTO", "DAG", "UG", "PDAG", "MPDAG", "ADMG", "AG", "UNKNOWN"), state = NULL, .session = NULL )
... |
Edge expressions using the supported infix operators, or
nodes given by symbols or strings. Multiple edges can be
combined using |
from |
Character vector of source node names.
Optional; mutually exclusive with |
edge |
Character vector of edge types.
Optional; mutually exclusive with |
to |
Character vector of target node names.
Optional; mutually exclusive with |
nodes |
Character vector of node names to declare as isolated nodes.
An optional, but recommended, option is to provide all node names in the
graph, including those that appear in edges. If |
edges_df |
Optional data.frame or data.table with columns
|
simple |
Logical; if |
build |
DEPRECATED. The graph is always built lazily, so this argument is ignored.
Can use |
class |
Character; one of |
state |
DEPRECATED. Replaced by |
.session |
For internal use. Build a graph by supplying a pre-constructed session pointer from Rust. |
A caugi S7 object containing the nodes, edges, and a
pointer to the underlying Rust graph structure.
# create a simple DAG (using NSE) cg <- caugi( A %-->% B + C, B %-->% D, class = "DAG" ) # create a PDAG with undirected edges (using NSE) cg2 <- caugi( A %-->% B + C, B %---% D, E, # no neighbors for this node class = "PDAG" ) # create a DAG (using SE) cg3 <- caugi( from = c("A", "A", "B"), edge = c("-->", "-->", "-->"), to = c("B", "C", "D"), nodes = c("A", "B", "C", "D", "E"), class = "DAG" ) # create a non-simple graph cg4 <- caugi( A %-->% B, B %-->% A, class = "UNKNOWN", simple = FALSE ) cg4@simple # FALSE cg4@graph_class # "UNKNOWN"# create a simple DAG (using NSE) cg <- caugi( A %-->% B + C, B %-->% D, class = "DAG" ) # create a PDAG with undirected edges (using NSE) cg2 <- caugi( A %-->% B + C, B %---% D, E, # no neighbors for this node class = "PDAG" ) # create a DAG (using SE) cg3 <- caugi( from = c("A", "A", "B"), edge = c("-->", "-->", "-->"), to = c("B", "C", "D"), nodes = c("A", "B", "C", "D", "E"), class = "DAG" ) # create a non-simple graph cg4 <- caugi( A %-->% B, B %-->% A, class = "UNKNOWN", simple = FALSE ) cg4@simple # FALSE cg4@graph_class # "UNKNOWN"
Returns the default options for the caugi package. Useful for resetting options to their original state.
caugi_default_options()caugi_default_options()
A list of default options for caugi.
caugi_options() for setting and getting options
# Get defaults caugi_default_options() # Reset to defaults caugi_options(caugi_default_options())# Get defaults caugi_default_options() # Reset to defaults caugi_options(caugi_default_options())
Converts a JSON string in the native caugi format back to a caugi graph.
This is a lower-level function; consider using read_caugi() for
reading from files.
caugi_deserialize(json, lazy)caugi_deserialize(json, lazy)
json |
Character string containing the JSON representation. |
lazy |
DEPRECATED, no longer necessary. The graph is always built lazily, so this argument is ignored. |
A caugi object.
Other export:
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi(A %-->% B, class = "DAG") json <- caugi_serialize(cg) cg2 <- caugi_deserialize(json)cg <- caugi(A %-->% B, class = "DAG") json <- caugi_serialize(cg) cg2 <- caugi_deserialize(json)
An S7 object that wraps a DOT format string for displaying caugi graphs. When printed interactively, displays the DOT string cleanly.
caugi_dot(content)caugi_dot(content)
content |
A character string containing the DOT format graph. |
Other export:
caugi_deserialize(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
A base class for all caugi export formats. Provides common structure and behavior for different export formats (DOT, GraphML, etc.).
caugi_export(content = character(0), format = character(0))caugi_export(content = character(0), format = character(0))
content |
A character string containing the exported graph. |
format |
A character string indicating the export format. |
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
An S7 object that wraps a GraphML format string for caugi graphs.
caugi_graphml(content)caugi_graphml(content)
content |
A character string containing the GraphML format graph. |
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Computes node coordinates for graph visualization using specified layout algorithm. If the graph has not been built yet, it will be built automatically before computing the layout.
caugi_layout( x, method = c("auto", "sugiyama", "fruchterman-reingold", "kamada-kawai", "bipartite", "tiered", "circle"), packing_ratio = 1.618034, ... )caugi_layout( x, method = c("auto", "sugiyama", "fruchterman-reingold", "kamada-kawai", "bipartite", "tiered", "circle"), packing_ratio = 1.618034, ... )
x |
A |
method |
Character string specifying the layout method. Options:
|
packing_ratio |
Aspect ratio for packing disconnected components
(width/height). Default is the golden ratio (1.618) which works well with
widescreen displays. Use |
... |
Additional arguments passed to the specific layout function.
For bipartite layouts, use |
A data.frame with columns name, x, and y containing node
names and their coordinates.
Sugiyama (Hierarchical Layout)
Optimized for directed acyclic graphs (DAGs). Places nodes in layers to emphasize hierarchical structure and causal flow from top to bottom. Edges are routed to minimize crossings. Best for visualizing clear cause-effect relationships. Only works with directed edges.
Fruchterman-Reingold (Spring-Electrical)
Fast force-directed layout using a spring-electrical model. Treats edges as springs and nodes as electrically charged particles. Produces organic, symmetric layouts with uniform edge lengths. Good for general-purpose visualization and works with all edge types. Results are deterministic.
Kamada-Kawai (Stress Minimization)
High-quality force-directed layout that minimizes "stress" by making Euclidean distances proportional to graph-theoretic distances. Better preserves the global structure and path lengths compared to Fruchterman-Reingold. Ideal for publication-quality visualizations where accurate distance representation matters. Works with all edge types and produces deterministic results.
Circle
Places nodes evenly along the perimeter of a circle. The first node is at the top and subsequent nodes proceed counter-clockwise. Useful for small graphs, cycle visualization, and as a deterministic fallback. Works with all edge types and ignores edge structure.
Fruchterman, T. M. J., & Reingold, E. M. (1991). Graph drawing by force-directed placement. Software: Practice and Experience, 21(11), 1129-1164. doi:10.1002/spe.4380211102
Kamada, T., & Kawai, S. (1989). An algorithm for drawing general undirected graphs. Information Processing Letters, 31(1), 7-15. doi:10.1016/0020-0190(89)90102-6
Sugiyama, K., Tagawa, S., & Toda, M. (1981). Methods for visual understanding of hierarchical system structures. IEEE Transactions on Systems, Man, and Cybernetics, 11(2), 109-125. doi:10.1109/TSMC.1981.4308636
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Default: auto-selects best layout layout <- caugi_layout(cg) # Auto-selects tiered when tiers provided cg_tiered <- caugi(X1 %-->% M1, X2 %-->% M2, M1 %-->% Y, M2 %-->% Y) tiers <- list(c("X1", "X2"), c("M1", "M2"), "Y") layout_auto <- caugi_layout(cg_tiered, tiers = tiers) # Uses "tiered" # Explicitly use hierarchical layout layout_sug <- caugi_layout(cg, method = "sugiyama") # Use force-directed for organic appearance layout_fr <- caugi_layout(cg, method = "fruchterman-reingold") # Use stress minimization for publication quality layout_kk <- caugi_layout(cg, method = "kamada-kawai") # Place nodes on a circle layout_circle <- caugi_layout(cg, method = "circle") # Bipartite layout with auto-detected partition cg_bp <- caugi(A %-->% X, A %-->% Y, B %-->% X, B %-->% Y) layout_bp_rows <- caugi_layout( cg_bp, method = "bipartite", orientation = "rows" ) # Explicit partition partition <- c(TRUE, TRUE, FALSE, FALSE) layout_bp_cols <- caugi_layout( cg_bp, method = "bipartite", partition = partition, orientation = "columns" ) # Tiered layout with three tiers cg_tiered <- caugi( X1 %-->% M1 + M2, X2 %-->% M1 + M2, M1 %-->% Y, M2 %-->% Y ) tiers <- list(c("X1", "X2"), c("M1", "M2"), "Y") layout_tiered <- caugi_layout( cg_tiered, method = "tiered", tiers = tiers, orientation = "rows" )cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Default: auto-selects best layout layout <- caugi_layout(cg) # Auto-selects tiered when tiers provided cg_tiered <- caugi(X1 %-->% M1, X2 %-->% M2, M1 %-->% Y, M2 %-->% Y) tiers <- list(c("X1", "X2"), c("M1", "M2"), "Y") layout_auto <- caugi_layout(cg_tiered, tiers = tiers) # Uses "tiered" # Explicitly use hierarchical layout layout_sug <- caugi_layout(cg, method = "sugiyama") # Use force-directed for organic appearance layout_fr <- caugi_layout(cg, method = "fruchterman-reingold") # Use stress minimization for publication quality layout_kk <- caugi_layout(cg, method = "kamada-kawai") # Place nodes on a circle layout_circle <- caugi_layout(cg, method = "circle") # Bipartite layout with auto-detected partition cg_bp <- caugi(A %-->% X, A %-->% Y, B %-->% X, B %-->% Y) layout_bp_rows <- caugi_layout( cg_bp, method = "bipartite", orientation = "rows" ) # Explicit partition partition <- c(TRUE, TRUE, FALSE, FALSE) layout_bp_cols <- caugi_layout( cg_bp, method = "bipartite", partition = partition, orientation = "columns" ) # Tiered layout with three tiers cg_tiered <- caugi( X1 %-->% M1 + M2, X2 %-->% M1 + M2, M1 %-->% Y, M2 %-->% Y ) tiers <- list(c("X1", "X2"), c("M1", "M2"), "Y") layout_tiered <- caugi_layout( cg_tiered, method = "tiered", tiers = tiers, orientation = "rows" )
Computes node coordinates for bipartite graphs, placing nodes in two parallel lines (rows or columns) based on a partition. If the graph has not been built yet, it will be built automatically before computing the layout.
caugi_layout_bipartite(x, partition = NULL, orientation = c("columns", "rows"))caugi_layout_bipartite(x, partition = NULL, orientation = c("columns", "rows"))
x |
A |
partition |
Optional logical vector indicating node partitions.
Nodes with |
orientation |
Character string specifying the layout orientation:
|
A data.frame with columns name, x, and y containing node
names and their coordinates.
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
# Create a bipartite graph (causes -> effects) cg <- caugi(A %-->% X, A %-->% Y, B %-->% X, B %-->% Y) partition <- c(TRUE, TRUE, FALSE, FALSE) # A, B = causes, X, Y = effects # Two horizontal rows (causes on top) layout_rows <- caugi_layout_bipartite(cg, partition, orientation = "rows") # Two vertical columns (causes on right) layout_cols <- caugi_layout_bipartite(cg, partition, orientation = "columns")# Create a bipartite graph (causes -> effects) cg <- caugi(A %-->% X, A %-->% Y, B %-->% X, B %-->% Y) partition <- c(TRUE, TRUE, FALSE, FALSE) # A, B = causes, X, Y = effects # Two horizontal rows (causes on top) layout_rows <- caugi_layout_bipartite(cg, partition, orientation = "rows") # Two vertical columns (causes on right) layout_cols <- caugi_layout_bipartite(cg, partition, orientation = "columns")
Computes node coordinates by placing nodes evenly along the perimeter of a circle. The first node is placed at the top of the circle, and subsequent nodes proceed counter-clockwise. Edge structure is ignored. Works with all edge types and produces deterministic results.
caugi_layout_circle(x, ...)caugi_layout_circle(x, ...)
x |
A |
... |
Ignored. For future extensibility. |
A data.frame with columns name, x, and y containing node
names and their coordinates.
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
cg <- caugi( A %-->% B, B %-->% C, C %-->% D, D %-->% A ) layout <- caugi_layout_circle(cg)cg <- caugi( A %-->% B, B %-->% C, C %-->% D, D %-->% A ) layout <- caugi_layout_circle(cg)
Computes node coordinates using the Fruchterman-Reingold force-directed layout algorithm. Fast spring-electrical model that treats edges as springs and nodes as electrically charged particles. Produces organic, symmetric layouts with uniform edge lengths. Works with all edge types and produces deterministic results.
caugi_layout_fruchterman_reingold(x, packing_ratio = 1.618034, ...)caugi_layout_fruchterman_reingold(x, packing_ratio = 1.618034, ...)
x |
A |
packing_ratio |
Aspect ratio for packing disconnected components
(width/height). Default is the golden ratio (1.618) which works well with
widescreen displays. Use |
... |
Ignored. For future extensibility. |
A data.frame with columns name, x, and y containing node
names and their coordinates.
Fruchterman, T. M. J., & Reingold, E. M. (1991). Graph drawing by force-directed placement. Software: Practice and Experience, 21(11), 1129-1164. doi:10.1002/spe.4380211102
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
cg <- caugi( A %-->% B, B %<->% C, C %-->% D ) layout <- caugi_layout_fruchterman_reingold(cg)cg <- caugi( A %-->% B, B %<->% C, C %-->% D ) layout <- caugi_layout_fruchterman_reingold(cg)
Computes node coordinates using the Kamada-Kawai stress minimization algorithm. High-quality force-directed layout that minimizes "stress" by making Euclidean distances proportional to graph-theoretic distances. Better preserves global structure and path lengths compared to Fruchterman-Reingold. Ideal for publication-quality visualizations. Works with all edge types and produces deterministic results.
caugi_layout_kamada_kawai(x, packing_ratio = 1.618034, ...)caugi_layout_kamada_kawai(x, packing_ratio = 1.618034, ...)
x |
A |
packing_ratio |
Aspect ratio for packing disconnected components
(width/height). Default is the golden ratio (1.618) which works well with
widescreen displays. Use |
... |
Ignored. For future extensibility. |
A data.frame with columns name, x, and y containing node
names and their coordinates.
Kamada, T., & Kawai, S. (1989). An algorithm for drawing general undirected graphs. Information Processing Letters, 31(1), 7-15. doi:10.1016/0020-0190(89)90102-6
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
cg <- caugi( A %-->% B, B %<->% C, C %-->% D ) layout <- caugi_layout_kamada_kawai(cg)cg <- caugi( A %-->% B, B %<->% C, C %-->% D ) layout <- caugi_layout_kamada_kawai(cg)
Computes node coordinates using the Sugiyama hierarchical layout algorithm. Optimized for directed acyclic graphs (DAGs), placing nodes in layers to emphasize hierarchical structure and causal flow from top to bottom.
caugi_layout_sugiyama(x, packing_ratio = 1.618034, ...)caugi_layout_sugiyama(x, packing_ratio = 1.618034, ...)
x |
A |
packing_ratio |
Aspect ratio for packing disconnected components
(width/height). Default is the golden ratio (1.618) which works well with
widescreen displays. Use |
... |
Ignored. For future extensibility. |
A data.frame with columns name, x, and y containing node
names and their coordinates.
Sugiyama, K., Tagawa, S., & Toda, M. (1981). Methods for visual understanding of hierarchical system structures. IEEE Transactions on Systems, Man, and Cybernetics, 11(2), 109-125. doi:10.1109/TSMC.1981.4308636
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
cg <- caugi(A %-->% B + C, B %-->% D, C %-->% D, class = "DAG") layout <- caugi_layout_sugiyama(cg)cg <- caugi(A %-->% B + C, B %-->% D, C %-->% D, class = "DAG") layout <- caugi_layout_sugiyama(cg)
Computes node coordinates for graphs with multiple tiers (layers), placing nodes in parallel rows or columns based on tier assignments. If the graph has not been built yet, it will be built automatically before computing the layout.
caugi_layout_tiered(x, tiers, orientation = c("columns", "rows"))caugi_layout_tiered(x, tiers, orientation = c("columns", "rows"))
x |
A |
tiers |
Tier assignments specifying which tier each node belongs to. Can be provided in multiple formats:
All nodes must be assigned to a tier, all tiers must be non-empty, and tier indices must be consecutive starting from 0 or 1. |
orientation |
Character string specifying the layout orientation:
|
A data.frame with columns name, x, y, and tier containing
node names, their coordinates, and tier assignments (0-indexed). The
returned data.frame also has an orientation attribute storing the
orientation used. When passed to plot(), tier information is
automatically extracted, so you don't need to specify tiers again.
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_plot(),
divide-caugi_plot-caugi_plot,
plot()
# Create a three-tier causal graph (exposures -> mediators -> outcome) cg <- caugi( X1 %-->% M1 + M2, X2 %-->% M1 + M2, M1 %-->% Y, M2 %-->% Y ) # Option 1: Named list (tier names are just labels) tiers <- list( exposures = c("X1", "X2"), mediators = c("M1", "M2"), outcome = "Y" ) layout_rows <- caugi_layout_tiered(cg, tiers, orientation = "rows") # Option 2: Named numeric vector (0-indexed or 1-indexed both work) tiers <- c(X1 = 1, X2 = 1, M1 = 2, M2 = 2, Y = 3) layout_cols <- caugi_layout_tiered(cg, tiers, orientation = "columns") # Option 3: Data.frame tiers <- data.frame( name = c("X1", "X2", "M1", "M2", "Y"), tier = c(1, 1, 2, 2, 3) ) layout <- caugi_layout_tiered(cg, tiers, orientation = "rows") # The layout includes tier information, so plot() works without passing tiers plot(cg, layout = layout)# Create a three-tier causal graph (exposures -> mediators -> outcome) cg <- caugi( X1 %-->% M1 + M2, X2 %-->% M1 + M2, M1 %-->% Y, M2 %-->% Y ) # Option 1: Named list (tier names are just labels) tiers <- list( exposures = c("X1", "X2"), mediators = c("M1", "M2"), outcome = "Y" ) layout_rows <- caugi_layout_tiered(cg, tiers, orientation = "rows") # Option 2: Named numeric vector (0-indexed or 1-indexed both work) tiers <- c(X1 = 1, X2 = 1, M1 = 2, M2 = 2, Y = 3) layout_cols <- caugi_layout_tiered(cg, tiers, orientation = "columns") # Option 3: Data.frame tiers <- data.frame( name = c("X1", "X2", "M1", "M2", "Y"), tier = c(1, 1, 2, 2, 3) ) layout <- caugi_layout_tiered(cg, tiers, orientation = "rows") # The layout includes tier information, so plot() works without passing tiers plot(cg, layout = layout)
An S7 object that wraps a Mermaid format string for displaying caugi graphs. When printed interactively, displays the Mermaid string cleanly.
caugi_mermaid(content)caugi_mermaid(content)
content |
A character string containing the Mermaid format graph. |
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Configure global defaults for caugi, including plot composition spacing and default visual styles for nodes, edges, labels, and titles.
caugi_options(...)caugi_options(...)
... |
Named values to update options with, or unnamed option names to retrieve. Multiple unnamed arguments drill down through nested options. To query all options, call without arguments. Attempting to access a non-existent option will raise an error. |
The use_open_graph_definition option (TRUE/FALSE, default TRUE)
controls how graph queries interpret reachability relations.
When TRUE (open definition), queries such as ancestors(),
descendants(), posteriors(),and anteriors()
exclude the queried node itself.
When FALSE (closed definition), the queried node is included in the
results.
The plot options are nested under the plot key:
spacing: A grid::unit() controlling space between composed plots
(default: grid::unit(1, "lines"))
node_style: List of default node appearance parameters:
fill: Fill color (default: "lightgrey")
padding: Padding around labels in mm (default: 2)
size: Size multiplier (default: 1)
edge_style: List of default edge appearance parameters:
arrow_size: Arrow size in mm (default: 3)
circle_size: Radius of endpoint circles for partial edges in mm (default: 1.5)
fill: Arrow/line color (default: "black")
label_style: List of label text parameters (see grid::gpar())
title_style: List of title text parameters:
col: Text color (default: "black")
fontface: Font face (default: "bold")
fontsize: Font size in pts (default: 14.4)
Options set via caugi_options() serve as global defaults that can be
overridden by arguments to plot().
When setting, returns (invisibly) the previous values for the updated options. When getting (no arguments or unnamed character vector), returns the requested options.
plot() for per-plot style arguments, grid::gpar() for
available graphical parameters
# Query all options caugi_options() # Use closed graph definition caugi_options(use_open_graph_definition = FALSE) # Query specific option caugi_options("plot") # Query nested option caugi_options("plot", "tier_style") caugi_options("plot", "node_style", "fill") # Set plot spacing caugi_options(plot = list(spacing = grid::unit(2, "lines"))) # Set default node style caugi_options(plot = list( node_style = list(fill = "lightblue", padding = 3) )) # Set multiple options at once caugi_options(plot = list( spacing = grid::unit(1.5, "lines"), node_style = list(fill = "lightblue", padding = 3), edge_style = list(arrow_size = 4, fill = "darkgray"), title_style = list(col = "blue", fontsize = 16) )) # Reset to defaults caugi_options(caugi_default_options())# Query all options caugi_options() # Use closed graph definition caugi_options(use_open_graph_definition = FALSE) # Query specific option caugi_options("plot") # Query nested option caugi_options("plot", "tier_style") caugi_options("plot", "node_style", "fill") # Set plot spacing caugi_options(plot = list(spacing = grid::unit(2, "lines"))) # Set default node style caugi_options(plot = list( node_style = list(fill = "lightblue", padding = 3) )) # Set multiple options at once caugi_options(plot = list( spacing = grid::unit(1.5, "lines"), node_style = list(fill = "lightblue", padding = 3), edge_style = list(arrow_size = 4, fill = "darkgray"), title_style = list(col = "blue", fontsize = 16) )) # Reset to defaults caugi_options(caugi_default_options())
An S7 object that wraps a grid gTree for displaying caugi graphs. Similar to ggplot objects, these are created by the plot method but not drawn until explicitly printed or plotted. This allows for returning plot objects from functions and controlling when/where they are displayed.
caugi_plot(grob = NULL)caugi_plot(grob = NULL)
grob |
A grid gTree representing the graph plot. |
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
divide-caugi_plot-caugi_plot,
plot()
Converts a caugi graph to a JSON string in the native caugi format.
This is a lower-level function; consider using write_caugi() for
writing to files.
caugi_serialize(x, comment = NULL, tags = NULL)caugi_serialize(x, comment = NULL, tags = NULL)
x |
A |
comment |
Optional character string with a comment about the graph. |
tags |
Optional character vector of tags for categorizing the graph. |
A character string containing the JSON representation.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi(A %-->% B, class = "DAG") json <- caugi_serialize(cg) cat(json)cg <- caugi(A %-->% B, class = "DAG") json <- caugi_serialize(cg) cat(json)
caugi
Add, remove, or and set nodes or edges to / from a caugi
object. Edges can be specified using expressions with the infix operators.
Alternatively, the edges to be added are specified using the
from, edge, and to arguments.
add_edges(cg, ..., from = NULL, edge = NULL, to = NULL, inplace = FALSE) remove_edges(cg, ..., from = NULL, edge = NULL, to = NULL, inplace = FALSE) set_edges(cg, ..., from = NULL, edge = NULL, to = NULL, inplace = FALSE) add_nodes(cg, ..., name = NULL, inplace = FALSE) remove_nodes(cg, ..., name = NULL, inplace = FALSE)add_edges(cg, ..., from = NULL, edge = NULL, to = NULL, inplace = FALSE) remove_edges(cg, ..., from = NULL, edge = NULL, to = NULL, inplace = FALSE) set_edges(cg, ..., from = NULL, edge = NULL, to = NULL, inplace = FALSE) add_nodes(cg, ..., name = NULL, inplace = FALSE) remove_nodes(cg, ..., name = NULL, inplace = FALSE)
cg |
A |
... |
Expressions specifying edges to add using the infix operators,
or nodes to add using unquoted names, vectors via |
from |
Character vector of source node names. Default is |
edge |
Character vector of edge types. Default is |
to |
Character vector of target node names. Default is |
inplace |
DEPRECATED This parameter is deprecated and will be ignored. Graphs are always modified via copy-on-write. |
name |
Character vector of node names. Default is |
Caugi graph verbs
The updated caugi.
add_edges(): Add edges.
remove_edges(): Remove edges.
set_edges(): Set edge type for given pair(s).
add_nodes(): Add nodes.
remove_nodes(): Remove nodes.
Other verbs:
build()
# initialize empty graph and build slowly cg <- caugi(class = "PDAG") cg <- cg |> add_nodes(c("A", "B", "C", "D", "E")) |> # A, B, C, D, E add_edges(A %-->% B %-->% C) |> # A --> B --> C, D, E set_edges(B %---% C) # A --> B --- C, D, E cg <- remove_edges(cg, B %---% C) |> # A --> B, C, D, E remove_nodes(c("C", "D", "E")) # A --> B # Graphs are now built lazily when needed parents(cg, "B") # triggers compilation# initialize empty graph and build slowly cg <- caugi(class = "PDAG") cg <- cg |> add_nodes(c("A", "B", "C", "D", "E")) |> # A, B, C, D, E add_edges(A %-->% B %-->% C) |> # A --> B --> C, D, E set_edges(B %---% C) # A --> B --- C, D, E cg <- remove_edges(cg, B %---% C) |> # A --> B, C, D, E remove_nodes(c("C", "D", "E")) # A --> B # Graphs are now built lazily when needed parents(cg, "B") # triggers compilation
caugi
Get children of nodes in a graph (nodes with directed edges pointing OUT
from the target nodes).
This is equivalent to neighbors(cg, nodes, mode = "out").
children(cg, nodes = NULL, index = NULL)children(cg, nodes = NULL, index = NULL)
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) children(cg, "A") # "B" children(cg, index = 2) # "C" children(cg, "B") # "C" children(cg, c("B", "C")) #> $B #> [1] "C" #> #> $C #> NULLcg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) children(cg, "A") # "B" children(cg, index = 2) # "C" children(cg, "B") # "C" children(cg, c("B", "C")) #> $B #> [1] "C" #> #> $C #> NULL
Marginalize variables out of an AG, and/or condition on variables. Depending on the structure, it could produce a graph with directed, bidirected, and undirected edges.
condition_marginalize(cg, cond_vars = NULL, marg_vars = NULL)condition_marginalize(cg, cond_vars = NULL, marg_vars = NULL)
cg |
A |
cond_vars |
Character vector of nodes to condition on. |
marg_vars |
Character vector of nodes to marginalize over. |
A caugi object of class "AG".
Definition 4.2.1 in Thomas Richardson. Peter Spirtes. "Ancestral graph Markov models." Ann. Statist. 30 (4) 962 - 1030, August 2002. doi:10.1214/aos/1031689015
Other operations:
dag_from_pdag(),
exogenize(),
latent_project(),
meek_closure(),
moralize(),
mutate_caugi(),
normalize_latent_structure(),
skeleton()
mg <- caugi( U %-->% X + Y, A %-->% X, B %-->% Y, class = "DAG" ) condition_marginalize(mg, marg_vars = "U") # ADMG condition_marginalize(mg, cond_vars = "U") # DAGmg <- caugi( U %-->% X + Y, A %-->% X, B %-->% Y, class = "DAG" ) condition_marginalize(mg, marg_vars = "U") # ADMG condition_marginalize(mg, cond_vars = "U") # DAG
Checks whether every node in X is d-separated from every node
in Y given Z in a DAG.
d_separated( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )d_separated( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )
cg |
A |
X, Y, Z
|
Character vectors of node names, or |
X_index, Y_index, Z_index
|
Optional numeric 1-based indices (exclusive
with |
TRUE if d-separated, FALSE otherwise.
Other adjustment:
adjustment_set(),
all_adjustment_sets_admg(),
all_backdoor_sets(),
is_valid_adjustment_admg(),
is_valid_backdoor(),
minimal_separator()
cg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) d_separated(cg, "X", "Y", Z = c("A", "D")) # TRUE d_separated(cg, "X", "Y", Z = NULL) # FALSEcg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) d_separated(cg, "X", "Y", Z = c("A", "D")) # TRUE d_separated(cg, "X", "Y", Z = NULL) # FALSE
Given a Partially Directed Acyclic Graph (PDAG), this function attempts to extend it to a Directed Acyclic Graph (DAG) by orienting the undirected edges while preserving acyclicity and all existing directed edges. The procedure implements the Dor-Tarsi algorithm.
If the PDAG cannot be consistently extended to a DAG, the function will raise an error.
dag_from_pdag(PDAG)dag_from_pdag(PDAG)
PDAG |
A |
A caugi object of class "DAG" representing a DAG extension
of the input PDAG.
Dor, D., & Tarsi, M. (1992). "A simple algorithm to construct a consistent extension of a partially directed acyclic graph".
Other operations:
condition_marginalize(),
exogenize(),
latent_project(),
meek_closure(),
moralize(),
mutate_caugi(),
normalize_latent_structure(),
skeleton()
PDAG <- caugi( A %---% B, B %---% C, class = "PDAG" ) DAG <- dag_from_pdag(PDAG) edges(DAG)PDAG <- caugi( A %---% B, B %---% C, class = "PDAG" ) DAG <- dag_from_pdag(PDAG) edges(DAG)
caugi
Get descendants of nodes in a caugi
descendants( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )descendants( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
open |
Boolean. Determines how the graph is interpreted when retrieving descendants.
Default is taken from |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) descendants(cg, "A") # "B" "C" descendants(cg, "A", open = FALSE) # "A" "B" "C" descendants(cg, index = 2) # "C" descendants(cg, "B") # "C" descendants(cg, c("B", "C")) #> $B #> [1] "C" #> #> $C #> NULLcg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) descendants(cg, "A") # "B" "C" descendants(cg, "A", open = FALSE) # "A" "B" "C" descendants(cg, index = 2) # "C" descendants(cg, "B") # "C" descendants(cg, c("B", "C")) #> $B #> [1] "C" #> #> $C #> NULL
Get districts (c-components) for all nodes, or for selected
nodes in an ADMG/AG. A district is a maximal set of nodes connected via
bidirected edges. If both nodes and index are NULL, returns all districts in the graph.
districts(cg, nodes = NULL, index = NULL, all = NULL)districts(cg, nodes = NULL, index = NULL, all = NULL)
cg |
A |
nodes |
Optional character vector of node names. If supplied, returns district(s) containing these nodes. |
index |
Optional numeric vector of 1-based node indices. If supplied, returns district(s) containing these indices. |
all |
DEPRECATED (If |
If all districts are requested: a list of character vectors, one per
district. If nodes/index are supplied: either a character vector (single
target) or a named list of character vectors (multiple targets).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, A %<->% C, D %<->% E, class = "ADMG" ) districts(cg) # Returns list with districts: {A, C}, {B}, {D, E} districts(cg, nodes = "A") # Returns c("A", "C") districts(cg, index = c(1, 4))cg <- caugi( A %-->% B, A %<->% C, D %<->% E, class = "ADMG" ) districts(cg) # Returns list with districts: {A, C}, {B}, {D, E} districts(cg, nodes = "A") # Returns c("A", "C") districts(cg, index = c(1, 4))
Stack two plots vertically with configurable spacing. Compositions can be nested to create complex multi-plot layouts.
e1 |
A |
e2 |
A |
The spacing between plots is controlled by the global option
caugi_options()$plot$spacing, which defaults to grid::unit(1, "lines").
Compositions can be nested arbitrarily:
p1 / p2 - two plots stacked vertically
p1 / p2 / p3 - three plots in a column
(p1 + p2) / p3 - two plots on top, one below
A caugi_plot object containing the composed layout
caugi_options() for configuring spacing and default styles
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
plot()
cg1 <- caugi(A %-->% B, B %-->% C) cg2 <- caugi(X %-->% Y, Y %-->% Z) p1 <- plot(cg1, main = "Graph 1") p2 <- plot(cg2, main = "Graph 2") # Vertical composition p1 / p2 # Mixed composition (p1 + p2) / p1cg1 <- caugi(A %-->% B, B %-->% C) cg2 <- caugi(X %-->% Y, Y %-->% Z) p1 <- plot(cg1, main = "Graph 1") p2 <- plot(cg2, main = "Graph 2") # Vertical composition p1 / p2 # Mixed composition (p1 + p2) / p1
caugi.Get the edge types of a caugi.
edge_types(cg)edge_types(cg)
cg |
A |
A character vector of edge types.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %--o% C, C %<->% D, D %---% E, A %o-o% E, class = "UNKNOWN" ) edge_types(cg) # returns c("-->", "o-o", "--o", "<->", "---")cg <- caugi( A %-->% B, B %--o% C, C %<->% D, D %---% E, A %o-o% E, class = "UNKNOWN" ) edge_types(cg) # returns c("-->", "o-o", "--o", "<->", "---")
caugi.Get edges of a caugi.
edges(cg, ...) E(cg, ...)edges(cg, ...) E(cg, ...)
cg |
A |
... |
Additional arguments (currently unused). |
A data.table with columns from, edge, and to.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, D, class = "DAG" ) edges(cg) # returns the data.table with columns from, edge, tocg <- caugi( A %-->% B, B %-->% C, D, class = "DAG" ) edges(cg) # returns the data.table with columns from, edge, to
Exogenize a graph by removing all ingoing edges to the set of nodes specified (i.e., make the nodes exogenous), as well as joining the parents of the nodes specified to the children of the nodes specified.
exogenize(cg, nodes)exogenize(cg, nodes)
cg |
A |
nodes |
A character vector of node names to exogenize. Must be a subset of the nodes in the graph. |
A caugi object representing the exogenized graph.
Other operations:
condition_marginalize(),
dag_from_pdag(),
latent_project(),
meek_closure(),
moralize(),
mutate_caugi(),
normalize_latent_structure(),
skeleton()
cg <- caugi(A %-->% B, class = "DAG") exogenize(cg, nodes = "B") # A, Bcg <- caugi(A %-->% B, class = "DAG") exogenize(cg, nodes = "B") # A, B
caugi
Get all exogenous nodes (nodes with no parents) in a
caugi.
exogenous(cg, undirected_as_parents = FALSE)exogenous(cg, undirected_as_parents = FALSE)
cg |
A |
undirected_as_parents |
Logical; if |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) exogenous(cg) # "A"cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) exogenous(cg) # "A"
S7 classes for representing caugi graphs in various export formats. These classes provide a common interface for serializing graphs to different text formats like DOT, GraphML, JSON, etc.
caugi_export is the base class for all export formats. It provides:
content property: Character string containing the serialized graph
format property: Character string indicating the format type
Common methods: print(), as.character(), knit_print()
caugi_dot: DOT format for Graphviz visualization
caugi_mermaid: Mermaid format for web-based visualization
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Functions for converting caugi graphs to and from the native caugi JSON format. This format provides efficient, reproducible serialization for saving and sharing caugi graphs.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Functions for converting caugi graphs to and from Graphviz DOT format. The DOT format is a plain text graph description language used by Graphviz tools for visualization.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Functions for converting caugi graphs to and from GraphML format. GraphML is an XML-based file format for graphs supported by many graph tools and libraries.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Functions for converting caugi graphs to Mermaid flowchart format. Mermaid is a JavaScript-based diagramming tool that renders in web browsers and is natively supported by Quarto, GitHub, and many other platforms.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
caugi using Erdős-Rényi.Sample a random DAG or CPDAG using Erdős-Rényi for random graph generation.
generate_graph(n, m = NULL, p = NULL, class = c("DAG", "CPDAG"), seed = NULL)generate_graph(n, m = NULL, p = NULL, class = c("DAG", "CPDAG"), seed = NULL)
n |
Integer >= 0. Number of nodes in the graph. |
m |
Integer in |
p |
Numeric in |
class |
"DAG" or "CPDAG". When |
seed |
Optional integer; random seed for reproducibility. |
The sampled caugi object. class = "DAG" returns a "DAG";
class = "CPDAG" returns an "MPDAG".
Other simulation functions:
simulate_data()
# generate a random DAG with 5 nodes and 4 edges dag <- generate_graph(n = 5, m = 4, class = "DAG") # generate a random CPDAG with 5 nodes and edge probability 0.3 # (returned as an MPDAG) mpdag <- generate_graph(n = 5, p = 0.3, class = "CPDAG")# generate a random DAG with 5 nodes and 4 edges dag <- generate_graph(n = 5, m = 4, class = "DAG") # generate a random CPDAG with 5 nodes and edge probability 0.3 # (returned as an MPDAG) mpdag <- generate_graph(n = 5, p = 0.3, class = "CPDAG")
Compute the Hamming Distance between two graphs.
hd(cg1, cg2, normalized = FALSE)hd(cg1, cg2, normalized = FALSE)
cg1 |
A |
cg2 |
A |
normalized |
Logical; if |
An integer representing the Hamming Distance between the two graphs,
if normalized = FALSE, or a numeric between 0 and 1 if normalized = TRUE.
cg1 <- caugi(A %-->% B %-->% C, D %-->% C, class = "DAG") cg2 <- caugi(A %-->% B %-->% C, D %---% C, class = "PDAG") hd(cg1, cg2) # 0cg1 <- caugi(A %-->% B %-->% C, D %-->% C, class = "DAG") cg2 <- caugi(A %-->% B %-->% C, D %---% C, class = "PDAG") hd(cg1, cg2) # 0
caugi acyclic?Checks if the given caugi graph is acyclic.
is_acyclic(cg, force_check = FALSE)is_acyclic(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
Logically, it should not be possible to have a graph class of "DAG", "PDAG", or "MPDAG" that has cycles, but in case the user modified the graph after creation in some unforeseen way that could have introduced cycles, this function allows to force a check of acyclicity, if needed.
A logical value indicating whether the graph is acyclic.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_acyclic <- caugi( A %-->% B, B %-->% C, class = "DAG" ) is_acyclic(cg_acyclic) # TRUE cg_cyclic <- caugi( A %-->% B, B %-->% C, C %-->% A, class = "UNKNOWN" ) is_acyclic(cg_cyclic) # FALSEcg_acyclic <- caugi( A %-->% B, B %-->% C, class = "DAG" ) is_acyclic(cg_acyclic) # TRUE cg_cyclic <- caugi( A %-->% B, B %-->% C, C %-->% A, class = "UNKNOWN" ) is_acyclic(cg_cyclic) # FALSE
caugi graph an ADMG?Checks if the given caugi graph is an
Acyclic Directed Mixed Graph (ADMG).
An ADMG contains only directed (-->) and bidirected (<->) edges,
and the directed part must be acyclic.
is_admg(cg, force_check = FALSE)is_admg(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is an ADMG.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_admg <- caugi( A %-->% B, A %<->% C, class = "ADMG" ) is_admg(cg_admg) # TRUE cg_dag <- caugi( A %-->% B, class = "DAG" ) is_admg(cg_dag) # TRUE (DAGs are valid ADMGs)cg_admg <- caugi( A %-->% B, A %<->% C, class = "ADMG" ) is_admg(cg_admg) # TRUE cg_dag <- caugi( A %-->% B, class = "DAG" ) is_admg(cg_dag) # TRUE (DAGs are valid ADMGs)
caugi graph an AG?Checks if the given caugi graph is an
Ancestral Graph (AG).
An AG contains directed (-->), bidirected (<->), and undirected (---)
edges, and must satisfy ancestral graph constraints (no directed cycles,
anterior constraint, and undirected constraint).
is_ag(cg, force_check = FALSE)is_ag(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is an AG.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_ag <- caugi( A %-->% B, C %<->% D, E %---% F, class = "AG" ) is_ag(cg_ag) # TRUE cg_ug <- caugi( A %---% B, class = "UG" ) is_ag(cg_ug) # TRUE (UGs are valid AGs)cg_ag <- caugi( A %-->% B, C %<->% D, E %---% F, class = "AG" ) is_ag(cg_ag) # TRUE cg_ug <- caugi( A %---% B, class = "UG" ) is_ag(cg_ug) # TRUE (UGs are valid AGs)
caugi graph?Checks if the given object is a caugi. Mostly used
internally to validate inputs.
is_caugi(x, throw_error = FALSE)is_caugi(x, throw_error = FALSE)
x |
An object to check. |
throw_error |
Logical; if |
A logical value indicating whether the object is a caugi.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, class = "DAG" ) is_caugi(cg) # TRUEcg <- caugi( A %-->% B, class = "DAG" ) is_caugi(cg) # TRUE
caugi graph a CPDAG?Checks if the given caugi graph is a
Complete Partially Directed Acyclic Graph (CPDAG).
is_cpdag(cg)is_cpdag(cg)
cg |
A |
A logical value indicating whether the graph is a CPDAG.
C. Meek (1995). Causal inference and causal explanation with background knowledge. In Proceedings of the Eleventh Conference on Uncertainty in Artificial Intelligence (UAI-95), pp. 403–411. Morgan Kaufmann.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_cpdag <- caugi( A %---% B, A %-->% C, B %-->% C, class = "PDAG" ) is_cpdag(cg_cpdag) # TRUE cg_not_cpdag <- caugi( A %---% B, A %---% C, B %-->% C, class = "PDAG" ) is_cpdag(cg_not_cpdag) # FALSEcg_cpdag <- caugi( A %---% B, A %-->% C, B %-->% C, class = "PDAG" ) is_cpdag(cg_cpdag) # TRUE cg_not_cpdag <- caugi( A %---% B, A %---% C, B %-->% C, class = "PDAG" ) is_cpdag(cg_not_cpdag) # FALSE
caugi graph a DAG?Checks if the given caugi graph is a
Directed Acyclic Graph (DAG).
is_dag(cg, force_check = FALSE)is_dag(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is a DAG.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_dag_class <- caugi( A %-->% B, class = "DAG" ) is_dag(cg_dag_class) # TRUE cg_dag_but_pdag_class <- caugi( A %-->% B, class = "PDAG" ) is_dag(cg_dag_but_pdag_class) # TRUE cg_cyclic <- caugi( A %-->% B, B %-->% C, C %-->% A, class = "UNKNOWN", simple = FALSE ) is_dag(cg_cyclic) # FALSE cg_undirected <- caugi( A %---% B, class = "UNKNOWN" ) is_dag(cg_undirected) # FALSEcg_dag_class <- caugi( A %-->% B, class = "DAG" ) is_dag(cg_dag_class) # TRUE cg_dag_but_pdag_class <- caugi( A %-->% B, class = "PDAG" ) is_dag(cg_dag_but_pdag_class) # TRUE cg_cyclic <- caugi( A %-->% B, B %-->% C, C %-->% A, class = "UNKNOWN", simple = FALSE ) is_dag(cg_cyclic) # FALSE cg_undirected <- caugi( A %---% B, class = "UNKNOWN" ) is_dag(cg_undirected) # FALSE
caugi graph empty?Checks if the given caugi graph is empty (has no nodes).
is_empty_caugi(cg)is_empty_caugi(cg)
cg |
A |
A logical value indicating whether the graph is empty.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_empty <- caugi(class = "DAG") is_empty_caugi(cg_empty) # TRUE cg_non_empty <- caugi( A %-->% B, class = "DAG" ) is_empty_caugi(cg_non_empty) # FALSE cg_no_edges_but_has_nodes <- caugi( A, B, class = "DAG" ) is_empty_caugi(cg_no_edges_but_has_nodes) # FALSEcg_empty <- caugi(class = "DAG") is_empty_caugi(cg_empty) # TRUE cg_non_empty <- caugi( A %-->% B, class = "DAG" ) is_empty_caugi(cg_non_empty) # FALSE cg_no_edges_but_has_nodes <- caugi( A, B, class = "DAG" ) is_empty_caugi(cg_no_edges_but_has_nodes) # FALSE
caugi graph a MAG?Checks if the given caugi graph is a
Maximal Ancestral Graph (MAG).
A MAG is an ancestral graph where no additional edge can be added without violating the ancestral graph constraints or changing the encoded independence model.
is_mag(cg, force_check = FALSE)is_mag(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is a MAG.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_ag <- caugi( A %-->% B, B %-->% C, class = "AG" ) is_mag(cg_ag) # TRUE (0 and 2 are m-separated by {B})cg_ag <- caugi( A %-->% B, B %-->% C, class = "AG" ) is_mag(cg_ag) # TRUE (0 and 2 are m-separated by {B})
caugi graph an MPDAG?Checks if the given caugi graph is a
Maximally oriented Partially Directed Acyclic Graph
(MPDAG), i.e. a PDAG where no additional edge orientations
are implied by Meek's rules (R1–R4).
is_mpdag(cg)is_mpdag(cg)
cg |
A |
If the graph is not PDAG-compatible, the function returns FALSE.
A logical value indicating whether the graph is an MPDAG.
C. Meek (1995). Causal inference and causal explanation with background knowledge. In Proceedings of the Eleventh Conference on Uncertainty in Artificial Intelligence (UAI-95), pp. 403–411. Morgan Kaufmann.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_not_mpdag <- caugi( A %---% B, A %-->% C, C %-->% B, class = "PDAG" ) is_mpdag(cg_not_mpdag) # FALSEcg_not_mpdag <- caugi( A %---% B, A %-->% C, C %-->% B, class = "PDAG" ) is_mpdag(cg_not_mpdag) # FALSE
caugi graph a PDAG?Checks if the given caugi graph is a
Partially Directed Acyclic Graph (PDAG).
is_pdag(cg, force_check = FALSE)is_pdag(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is a PDAG.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_dag_class <- caugi( A %-->% B, class = "DAG" ) is_pdag(cg_dag_class) # TRUE cg_dag_but_pdag_class <- caugi( A %-->% B, class = "PDAG" ) is_pdag(cg_dag_but_pdag_class) # TRUE cg_cyclic <- caugi( A %-->% B, B %-->% C, C %-->% A, D %---% A, class = "UNKNOWN", simple = FALSE ) is_pdag(cg_cyclic) # FALSE cg_undirected <- caugi( A %---% B, class = "UNKNOWN" ) is_pdag(cg_undirected) # TRUE cg_pag <- caugi( A %o->% B, class = "UNKNOWN" ) is_pdag(cg_pag) # FALSEcg_dag_class <- caugi( A %-->% B, class = "DAG" ) is_pdag(cg_dag_class) # TRUE cg_dag_but_pdag_class <- caugi( A %-->% B, class = "PDAG" ) is_pdag(cg_dag_but_pdag_class) # TRUE cg_cyclic <- caugi( A %-->% B, B %-->% C, C %-->% A, D %---% A, class = "UNKNOWN", simple = FALSE ) is_pdag(cg_cyclic) # FALSE cg_undirected <- caugi( A %---% B, class = "UNKNOWN" ) is_pdag(cg_undirected) # TRUE cg_pag <- caugi( A %o->% B, class = "UNKNOWN" ) is_pdag(cg_pag) # FALSE
caugi graph simple?Checks if the given caugi graph is simple (no self-loops and
no parallel edges).
is_simple(cg, force_check = FALSE)is_simple(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is simple.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_simple <- caugi( A %-->% B, class = "DAG" ) is_simple(cg_simple) # TRUE cg_nonsimple <- caugi( A %-->% B, A %<->% B, class = "UNKNOWN", simple = FALSE ) is_simple(cg_nonsimple) # FALSEcg_simple <- caugi( A %-->% B, class = "DAG" ) is_simple(cg_simple) # TRUE cg_nonsimple <- caugi( A %-->% B, A %<->% B, class = "UNKNOWN", simple = FALSE ) is_simple(cg_nonsimple) # FALSE
caugi graph an UG?Checks if the given caugi graph is an undirected graph (UG).
is_ug(cg, force_check = FALSE)is_ug(cg, force_check = FALSE)
cg |
A |
force_check |
Logical; if |
A logical value indicating whether the graph is an UG.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg_ug_class <- caugi( A %---% B, class = "UG" ) is_ug(cg_ug_class) # TRUE cg_not_ug <- caugi( A %-->% B, class = "DAG" ) is_ug(cg_not_ug) # FALSEcg_ug_class <- caugi( A %---% B, class = "UG" ) is_ug(cg_ug_class) # TRUE cg_not_ug <- caugi( A %-->% B, class = "DAG" ) is_ug(cg_not_ug) # FALSE
Checks whether Z is a valid adjustment set for estimating
the causal effect of X on Y in an ADMG using the generalized adjustment
criterion.
is_valid_adjustment_admg( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )is_valid_adjustment_admg( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )
cg |
A |
X, Y
|
Node names (can be vectors for multiple treatments/outcomes). |
Z |
Conditioning set (character vector of node names). |
X_index, Y_index, Z_index
|
Optional 1-based indices. |
Logical value indicating if the adjustment set is valid.
Other adjustment:
adjustment_set(),
all_adjustment_sets_admg(),
all_backdoor_sets(),
d_separated(),
is_valid_backdoor(),
minimal_separator()
# Classic confounding cg <- caugi( L %-->% X, X %-->% Y, L %-->% Y, class = "ADMG" ) is_valid_adjustment_admg(cg, X = "X", Y = "Y", Z = NULL) # FALSE is_valid_adjustment_admg(cg, X = "X", Y = "Y", Z = "L") # TRUE# Classic confounding cg <- caugi( L %-->% X, X %-->% Y, L %-->% Y, class = "ADMG" ) is_valid_adjustment_admg(cg, X = "X", Y = "Y", Z = NULL) # FALSE is_valid_adjustment_admg(cg, X = "X", Y = "Y", Z = "L") # TRUE
Checks whether Z is a valid backdoor adjustment set for
X --> Y.
is_valid_backdoor( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )is_valid_backdoor( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )
cg |
A |
X, Y
|
Single node names. |
Z |
Optional node set for conditioning |
X_index, Y_index, Z_index
|
Optional 1-based indices. |
Logical value indicating if backdoor is valid or not.
Other adjustment:
adjustment_set(),
all_adjustment_sets_admg(),
all_backdoor_sets(),
d_separated(),
is_valid_adjustment_admg(),
minimal_separator()
cg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) is_valid_backdoor(cg, X = "X", Y = "Y", Z = NULL) # FALSE is_valid_backdoor(cg, X = "X", Y = "Y", Z = "K") # TRUE is_valid_backdoor(cg, X = "X", Y = "Y", Z = c("A", "C")) # TRUEcg <- caugi( C %-->% X, X %-->% F, X %-->% D, A %-->% X, A %-->% K, K %-->% Y, D %-->% Y, D %-->% G, Y %-->% H, class = "DAG" ) is_valid_backdoor(cg, X = "X", Y = "Y", Z = NULL) # FALSE is_valid_backdoor(cg, X = "X", Y = "Y", Z = "K") # TRUE is_valid_backdoor(cg, X = "X", Y = "Y", Z = c("A", "C")) # TRUE
Renders caugi export objects as code blocks in Quarto/R Markdown documents. This method is automatically invoked when an export object is the last expression in a code chunk.
x |
A |
... |
Additional arguments (currently unused). |
This method enables seamless rendering of caugi graphs in Quarto and
R Markdown. The code block type is determined by the export format.
Simply use an export function (e.g., to_dot(cg)) as the last expression
in a chunk with output: asis:
#| output: asis to_dot(cg)
A knit_asis object for rendering by knitr.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
Projects out latent (unobserved) variables from a DAG to produce an Acyclic Directed Mixed Graph (ADMG) over the observed variables.
latent_project(cg, latents)latent_project(cg, latents)
cg |
A |
latents |
Character vector of latent variable names to project out. |
A caugi object of class "ADMG" containing only the observed
variables.
Other operations:
condition_marginalize(),
dag_from_pdag(),
exogenize(),
meek_closure(),
moralize(),
mutate_caugi(),
normalize_latent_structure(),
skeleton()
# DAG with latent confounder U dag <- caugi( U %-->% X, U %-->% Y, X %-->% Y, class = "DAG" ) # Project out the latent variable admg <- latent_project(dag, latents = "U") # Result: X -> Y, X <-> Y (children of U become bidirected-connected) edges(admg) # DAG with directed path through latent dag2 <- caugi( X %-->% L, L %-->% Y, class = "DAG" ) # Project out the latent variable admg2 <- latent_project(dag2, latents = "L") # Result: X -> Y (directed path X -> L -> Y becomes X -> Y) edges(admg2)# DAG with latent confounder U dag <- caugi( U %-->% X, U %-->% Y, X %-->% Y, class = "DAG" ) # Project out the latent variable admg <- latent_project(dag, latents = "U") # Result: X -> Y, X <-> Y (children of U become bidirected-connected) edges(admg) # DAG with directed path through latent dag2 <- caugi( X %-->% L, L %-->% Y, class = "DAG" ) # Project out the latent variable admg2 <- latent_project(dag2, latents = "L") # Result: X -> Y (directed path X -> L -> Y becomes X -> Y) edges(admg2)
caugi
Returns the number of nodes in the graph.
x |
A |
An integer representing the number of nodes.
Other caugi methods:
caugi-equality,
print()
cg <- caugi( A %-->% B, class = "DAG" ) length(cg) # 2 cg2 <- caugi( A %-->% B + C, nodes = LETTERS[1:5], class = "DAG" ) length(cg2) # 5cg <- caugi( A %-->% B, class = "DAG" ) length(cg) # 2 cg2 <- caugi( A %-->% B + C, nodes = LETTERS[1:5], class = "DAG" ) length(cg2) # 5
Test whether two sets of nodes are m-separated given a conditioning set in an ancestral graph (AG) or an ADMG.
M-separation generalizes d-separation to AGs/ADMGs and applies to DAGs.
m_separated( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )m_separated( cg, X = NULL, Y = NULL, Z = NULL, X_index = NULL, Y_index = NULL, Z_index = NULL )
cg |
A |
X, Y, Z
|
Character vectors of node names, or |
X_index, Y_index, Z_index
|
Optional numeric 1-based indices (exclusive
with |
A logical value; TRUE if X and Y are m-separated given Z.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
# Classic confounding example cg <- caugi( L %-->% X, X %-->% Y, L %-->% Y, class = "ADMG" ) m_separated(cg, X = "X", Y = "Y") # FALSE (connected via L) m_separated(cg, X = "X", Y = "Y", Z = "L") # TRUE (L blocks the path)# Classic confounding example cg <- caugi( L %-->% X, X %-->% Y, L %-->% Y, class = "ADMG" ) m_separated(cg, X = "X", Y = "Y") # FALSE (connected via L) m_separated(cg, X = "X", Y = "Y", Z = "L") # TRUE (L blocks the path)
caugi
Get Markov blanket of nodes in a caugi
markov_blanket(cg, nodes = NULL, index = NULL)markov_blanket(cg, nodes = NULL, index = NULL)
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) markov_blanket(cg, "A") # "B" markov_blanket(cg, index = 2) # "A" "C" markov_blanket(cg, "B") # "A" "C" markov_blanket(cg, c("B", "C")) #> $B #> [1] "A" "C" #> #> $C #> [1] "B"cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) markov_blanket(cg, "A") # "B" markov_blanket(cg, index = 2) # "A" "C" markov_blanket(cg, "B") # "A" "C" markov_blanket(cg, c("B", "C")) #> $B #> [1] "A" "C" #> #> $C #> [1] "B"
Applies Meek's orientation rules (R1–R4) repeatedly to a PDAG until no more orientations are implied.
meek_closure(cg)meek_closure(cg)
cg |
A |
A caugi object closed under Meek's rules. Class "MPDAG" in
general, or "DAG" if the closure orients every edge.
C. Meek (1995). Causal inference and causal explanation with background knowledge. In Proceedings of the Eleventh Conference on Uncertainty in Artificial Intelligence (UAI-95), pp. 403–411. Morgan Kaufmann.
Other operations:
condition_marginalize(),
dag_from_pdag(),
exogenize(),
latent_project(),
moralize(),
mutate_caugi(),
normalize_latent_structure(),
skeleton()
pdag <- caugi( A %---% B, A %-->% C, C %-->% B, class = "PDAG" ) mpdag <- meek_closure(pdag) edges(mpdag)pdag <- caugi( A %---% B, A %-->% C, C %-->% B, class = "PDAG" ) mpdag <- meek_closure(pdag) edges(mpdag)
Computes a minimal separator Z for sets X and Y, optionally with mandatory inclusions and restrictions on the separator. Supports DAGs (where the result is a d-separator), ADMGs, and ancestral graphs (where the result is an m-separator).
minimal_separator( cg, X = NULL, Y = NULL, I = character(0), R = NULL, X_index = NULL, Y_index = NULL, I_index = NULL, R_index = NULL ) minimal_d_separator( cg, X = NULL, Y = NULL, I = character(0), R = NULL, X_index = NULL, Y_index = NULL, I_index = NULL, R_index = NULL )minimal_separator( cg, X = NULL, Y = NULL, I = character(0), R = NULL, X_index = NULL, Y_index = NULL, I_index = NULL, R_index = NULL ) minimal_d_separator( cg, X = NULL, Y = NULL, I = character(0), R = NULL, X_index = NULL, Y_index = NULL, I_index = NULL, R_index = NULL )
cg |
A |
X, Y
|
Character vectors of node names. Use |
I |
Nodes that must be included in the separator. |
R |
Nodes allowed in the separator. If |
X_index, Y_index, I_index, R_index
|
Optional numeric 1-based indices (exclusive with corresponding name parameters). |
A separator Z for X and Y is a set of nodes such that conditioning on Z d- or m-separates X from Y in the graph. This function returns a minimal separator: no proper subset of Z (excluding I) still separates X and Y.
The algorithm runs in linear time O(n + m) and is unified across graph classes via the Bayes-ball reachability of van der Zander & Liśkiewicz (2020). For DAGs the algorithm specializes to FINDMINSEPINDAG; for ADMGs and AGs (and their subclasses CPDAG, RCG, MAG) it uses the general FINDMINSEP over mixed graphs.
A character vector of node names representing the minimal separator,
or NULL if no valid separator exists within the restriction R.
van der Zander, B. & Liśkiewicz, M. (2020). Finding Minimal d-separators in Linear Time and Applications. Proceedings of The 35th Uncertainty in Artificial Intelligence Conference, in Proceedings of Machine Learning Research 115:637-647 Available from https://proceedings.mlr.press/v115/van-der-zander20a.html.
van der Zander, B. & Liśkiewicz, M. (2020). Finding Minimal d-separators in Linear Time and Applications. In Proceedings of the 35th Conference on Uncertainty in Artificial Intelligence (UAI 2020), PMLR 115:637–647. https://proceedings.mlr.press/v115/van-der-zander20a.html.
Other adjustment:
adjustment_set(),
all_adjustment_sets_admg(),
all_backdoor_sets(),
d_separated(),
is_valid_adjustment_admg(),
is_valid_backdoor()
cg <- caugi( A %-->% X, X %-->% M, M %-->% Y, A %-->% Y, class = "DAG" ) # Find any minimal separator between X and Y minimal_separator(cg, "X", "Y") # Force M to be in the separator minimal_separator(cg, "X", "Y", I = "M") # Restrict separator to only {A, M} minimal_separator(cg, "X", "Y", R = c("A", "M")) # Works on ADMGs (returns a minimal m-separator) admg <- caugi( X %-->% Y, L %-->% X, L %-->% Y, class = "ADMG" ) minimal_separator(admg, "X", "Y")cg <- caugi( A %-->% X, X %-->% M, M %-->% Y, A %-->% Y, class = "DAG" ) # Find any minimal separator between X and Y minimal_separator(cg, "X", "Y") # Force M to be in the separator minimal_separator(cg, "X", "Y", I = "M") # Restrict separator to only {A, M} minimal_separator(cg, "X", "Y", R = c("A", "M")) # Works on ADMGs (returns a minimal m-separator) admg <- caugi( X %-->% Y, L %-->% X, L %-->% Y, class = "ADMG" ) minimal_separator(admg, "X", "Y")
Moralizing a DAG involves connecting all parents of each node and then converting all directed edges into undirected edges.
moralize(cg)moralize(cg)
cg |
A |
This changes the graph from a Directed Acyclic Graph (DAG) to an Undirected Graph (UG), also known as a Markov Graph.
A caugi object representing the moralized graph (UG).
Other operations:
condition_marginalize(),
dag_from_pdag(),
exogenize(),
latent_project(),
meek_closure(),
mutate_caugi(),
normalize_latent_structure(),
skeleton()
cg <- caugi(A %-->% C, B %-->% C, class = "DAG") moralize(cg) # A -- B, A -- C, B -- Ccg <- caugi(A %-->% C, B %-->% C, class = "DAG") moralize(cg) # A -- B, A -- C, B -- C
caugi classMutate the caugi class from one graph class to another, if possible.
For example, convert a DAG to a PDAG, or a fully directed caugi of
class UNKNOWN to a DAG. Throws an error if not possible.
mutate_caugi(cg, class)mutate_caugi(cg, class)
cg |
A |
class |
A character string specifying the new class. |
This function returns a copy of the object, and the original remains unchanged.
A caugi object of the specified class.
Other operations:
condition_marginalize(),
dag_from_pdag(),
exogenize(),
latent_project(),
meek_closure(),
moralize(),
normalize_latent_structure(),
skeleton()
cg <- caugi(A %-->% B, class = "UNKNOWN") cg_dag <- mutate_caugi(cg, "DAG")cg <- caugi(A %-->% B, class = "UNKNOWN") cg_dag <- mutate_caugi(cg, "DAG")
caugi
Get neighbors of a node in the graph, optionally filtered by edge direction
or type. This function works for all graph classes including UNKNOWN.
neighbors(cg, nodes = NULL, index = NULL, mode = "all") neighbours(cg, nodes = NULL, index = NULL, mode = "all")neighbors(cg, nodes = NULL, index = NULL, mode = "all") neighbours(cg, nodes = NULL, index = NULL, mode = "all")
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
mode |
Character; specifies which types of neighbors to return:
Not all modes are valid for all graph classes:
|
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) neighbors(cg, "A") # "B" neighbors(cg, index = 2) # "A" "C" neighbors(cg, "B") # "A" "C" neighbors(cg, c("B", "C")) #> $B #> [1] "A" "C" #> #> $C #> [1] "B" # Using mode to filter by edge direction neighbors(cg, "B", mode = "in") # "A" (parents) neighbors(cg, "B", mode = "out") # "C" (children) # Works for UNKNOWN graphs too cg_unknown <- caugi( A %-->% B, B %---% C, C %o->% D, class = "UNKNOWN" ) neighbors(cg_unknown, "B", mode = "in") # "A" neighbors(cg_unknown, "B", mode = "undirected") # "C" neighbors(cg_unknown, "C", mode = "partial") # "D"cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) neighbors(cg, "A") # "B" neighbors(cg, index = 2) # "A" "C" neighbors(cg, "B") # "A" "C" neighbors(cg, c("B", "C")) #> $B #> [1] "A" "C" #> #> $C #> [1] "B" # Using mode to filter by edge direction neighbors(cg, "B", mode = "in") # "A" (parents) neighbors(cg, "B", mode = "out") # "C" (children) # Works for UNKNOWN graphs too cg_unknown <- caugi( A %-->% B, B %---% C, C %o->% D, class = "UNKNOWN" ) neighbors(cg_unknown, "B", mode = "in") # "A" neighbors(cg_unknown, "B", mode = "undirected") # "C" neighbors(cg_unknown, "C", mode = "partial") # "D"
caugi
Get nodes or edges of a caugi
nodes(cg, ...) vertices(cg, ...) V(cg, ...)nodes(cg, ...) vertices(cg, ...) V(cg, ...)
cg |
A |
... |
Additional arguments (currently unused). |
A data.table with a name column.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, D, class = "DAG" ) nodes(cg) # returns the data.table with nodes A, B, C, Dcg <- caugi( A %-->% B, B %-->% C, D, class = "DAG" ) nodes(cg) # returns the data.table with nodes A, B, C, D
Normalizes a DAG with latent variables while preserving the induced marginal model over the observed variables. This is done by:
(1) exogenizing all latent nodes (making them parentless), (2) removing exogenous latent nodes with at most one child, and (3) removing exogenous latent nodes whose child sets are strict subsets of another latent node's child set.
This corresponds to Lemmas 1–3 in Evans (2016).
normalize_latent_structure(cg, latents)normalize_latent_structure(cg, latents)
cg |
A |
latents |
Character vector of latent node names. |
A caugi object of class "DAG".
Evans, R. J. (2016). Graphs for margins of Bayesian networks. Scandinavian Journal of Statistics, 43(3), 625–648. doi:10.1111/sjos.12194
Other operations:
condition_marginalize(),
dag_from_pdag(),
exogenize(),
latent_project(),
meek_closure(),
moralize(),
mutate_caugi(),
skeleton()
dag <- caugi( A %-->% U, U %-->% X + Y, class = "DAG" ) normalize_latent_structure(dag, latents = "U") # More complex example with two latents and nested child sets dag2 <- caugi( A %-->% U, U %-->% X + Y + Z, U2 %-->% Y + Z, class = "DAG" ) normalize_latent_structure(dag2, c("U", "U2"))dag <- caugi( A %-->% U, U %-->% X + Y, class = "DAG" ) normalize_latent_structure(dag, latents = "U") # More complex example with two latents and nested child sets dag2 <- caugi( A %-->% U, U %-->% X + Y + Z, U2 %-->% Y + Z, class = "DAG" ) normalize_latent_structure(dag2, c("U", "U2"))
caugi
Get parents of nodes in a graph (nodes with directed edges pointing INTO
the target node). This is equivalent to neighbors(cg, nodes, mode = "in").
Note that not both nodes and index can be given.
parents(cg, nodes = NULL, index = NULL)parents(cg, nodes = NULL, index = NULL)
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
posteriors(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) parents(cg, "A") # NULL parents(cg, index = 2) # "A" parents(cg, "B") # "A" parents(cg, c("B", "C")) #> $B #> [1] "A" #> #> $C #> [1] "B"cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) parents(cg, "A") # NULL parents(cg, index = 2) # "A" parents(cg, "B") # "A" parents(cg, c("B", "C")) #> $B #> [1] "A" #> #> $C #> [1] "B"
Creates a grid graphics object (gTree) representing a caugi graph.
If the graph has not been built yet, it will be built automatically before
plotting. This implementation uses idiomatic grid graphics with viewports
for proper coordinate handling.
x |
A |
layout |
Specifies the graph layout method. Can be:
|
... |
Additional arguments passed to |
node_style |
List of node styling parameters. Supports:
|
edge_style |
List of edge styling parameters. Can specify global options
or per-type options via
|
label_style |
List of label styling parameters. Supports:
|
tier_style |
List of tier box styling parameters. Tier boxes are shown
when
|
main |
Optional character string for plot title. If |
title_style |
List of title styling parameters. Supports:
|
asp |
Numeric value for the y/x aspect ratio. If |
outer_margin |
Grid unit specifying outer margin around the plot.
Default is |
title_gap |
Grid unit specifying gap between title and graph.
Default is |
A caugi_plot object that wraps a gTree for grid graphics
display. The plot is automatically drawn when printed or explicitly
plotted.
Other plotting:
add-caugi_plot-caugi_plot,
caugi_layout(),
caugi_layout_bipartite(),
caugi_layout_circle(),
caugi_layout_fruchterman_reingold(),
caugi_layout_kamada_kawai(),
caugi_layout_sugiyama(),
caugi_layout_tiered(),
caugi_plot(),
divide-caugi_plot-caugi_plot
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) plot(cg) # Use a specific layout method (as string) plot(cg, layout = "kamada-kawai") # Use a layout function plot(cg, layout = caugi_layout_sugiyama) # Pre-compute layout and use it coords <- caugi_layout_fruchterman_reingold(cg) plot(cg, layout = coords) # Bipartite layout with a function cg_bp <- caugi(A %-->% X, B %-->% X, C %-->% Y) partition <- c(TRUE, TRUE, TRUE, FALSE, FALSE) plot(cg_bp, layout = caugi_layout_bipartite, partition = partition) # Customize nodes plot(cg, node_style = list(fill = "lightgreen", padding = 0.8)) # Customize edges by type plot( cg, edge_style = list( directed = list(col = "blue", arrow_size = 4), undirected = list(col = "red") ) ) # Add a title plot(cg, main = "Causal Graph") # Customize title plot( cg, main = "My Graph", title_style = list(fontsize = 18, col = "blue", fontface = "italic") ) # Respect aspect ratio (1:1) plot(cg, asp = 1)cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) plot(cg) # Use a specific layout method (as string) plot(cg, layout = "kamada-kawai") # Use a layout function plot(cg, layout = caugi_layout_sugiyama) # Pre-compute layout and use it coords <- caugi_layout_fruchterman_reingold(cg) plot(cg, layout = coords) # Bipartite layout with a function cg_bp <- caugi(A %-->% X, B %-->% X, C %-->% Y) partition <- c(TRUE, TRUE, TRUE, FALSE, FALSE) plot(cg_bp, layout = caugi_layout_bipartite, partition = partition) # Customize nodes plot(cg, node_style = list(fill = "lightgreen", padding = 0.8)) # Customize edges by type plot( cg, edge_style = list( directed = list(col = "blue", arrow_size = 4), undirected = list(col = "red") ) ) # Add a title plot(cg, main = "Causal Graph") # Customize title plot( cg, main = "My Graph", title_style = list(fontsize = 18, col = "blue", fontface = "italic") ) # Respect aspect ratio (1:1) plot(cg, asp = 1)
caugi
Get the posterior set of nodes in a graph. The posterior set (dual of the anterior set from Richardson and Spirtes, 2002) includes all nodes reachable by following paths where every edge is either undirected or directed away from the source node.
For DAGs, the posterior set equals the descendant set (since there are no undirected edges). For PDAGs, it includes both descendants and nodes reachable via undirected edges.
posteriors( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )posteriors( cg, nodes = NULL, index = NULL, open = caugi_options("use_open_graph_definition") )
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
open |
Boolean. Determines how the graph is interpreted when retrieving posteriors.
Default is taken from |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
same_nodes(),
spouses(),
subgraph(),
topological_sort()
# PDAG example with directed and undirected edges cg <- caugi( A %-->% B %---% C, B %-->% D, class = "PDAG" ) posteriors(cg, "A") # B, C, D posteriors(cg, "A", open = FALSE) # A, B, C, D posteriors(cg, "B") # C, D posteriors(cg, "D") # NULL (no posteriors) # For DAGs, posteriors equals descendants cg_dag <- caugi( A %-->% B %-->% C, class = "DAG" ) posteriors(cg_dag, "A") # B, C# PDAG example with directed and undirected edges cg <- caugi( A %-->% B %---% C, B %-->% D, class = "PDAG" ) posteriors(cg, "A") # B, C, D posteriors(cg, "A", open = FALSE) # A, B, C, D posteriors(cg, "B") # C, D posteriors(cg, "D") # NULL (no posteriors) # For DAGs, posteriors equals descendants cg_dag <- caugi( A %-->% B %-->% C, class = "DAG" ) posteriors(cg_dag, "A") # B, C
caugi
Print a caugi
x |
A |
max_nodes |
Optional numeric; maximum number of node names to consider.
If |
max_edges |
Optional numeric; maximum number of edges to consider.
If |
... |
Not used. |
The input caugi object, invisibly.
Other caugi methods:
caugi-equality,
length()
cg <- caugi(A %-->% B, class = "DAG") print(cg)cg <- caugi(A %-->% B, class = "DAG") print(cg)
Reads a caugi graph from a file in the native caugi JSON format.
read_caugi(path, lazy)read_caugi(path, lazy)
path |
Character string specifying the file path. |
lazy |
DEPRECATED, no longer necessary. The graph is always built lazily, so this argument is ignored. |
The function validates the file format and version, ensuring compatibility with the current version of the caugi package.
A caugi object.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi( A %-->% B + C, class = "DAG" ) # Write and read tmp <- tempfile(fileext = ".caugi.json") write_caugi(cg, tmp) cg2 <- read_caugi(tmp) # Clean up unlink(tmp)cg <- caugi( A %-->% B + C, class = "DAG" ) # Write and read tmp <- tempfile(fileext = ".caugi.json") write_caugi(cg, tmp) cg2 <- read_caugi(tmp) # Clean up unlink(tmp)
Imports a GraphML file as a caugi graph. Supports GraphML files exported from caugi with full edge type information.
read_graphml(path, class = NULL)read_graphml(path, class = NULL)
path |
File path to the GraphML file. |
class |
Graph class to assign. If |
This function provides basic GraphML import support. It reads:
Nodes and their IDs
Edges with source and target
Edge types (if present in edge_type attribute)
Graph class (if present in graph data)
For GraphML files not created by caugi, edge types default to "–>" for directed graphs and "—" for undirected graphs.
A caugi object.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
# Create and export a graph cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) tmp <- tempfile(fileext = ".graphml") write_graphml(cg, tmp) # Read it back cg2 <- read_graphml(tmp) # Clean up unlink(tmp)# Create and export a graph cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) tmp <- tempfile(fileext = ".graphml") write_graphml(cg, tmp) # Read it back cg2 <- read_graphml(tmp) # Clean up unlink(tmp)
Register a new edge type in the global registry.
register_caugi_edge(glyph, tail_mark, head_mark, class, symmetric = FALSE)register_caugi_edge(glyph, tail_mark, head_mark, class, symmetric = FALSE)
glyph |
A string representing the edge glyph (e.g., |
tail_mark |
One of "arrow", "tail", "circle", "other". |
head_mark |
One of "arrow", "tail", "circle", "other". |
class |
One of "directed","undirected","bidirected","partial". |
symmetric |
Logical. |
TRUE, invisibly.
Other registry:
registry
# first, for reproducability, we reset the registry to default reset_caugi_registry() # create a new registry reg <- caugi_registry() # register an edge register_caugi_edge( glyph = "<--", tail_mark = "arrow", head_mark = "tail", class = "directed", symmetric = FALSE ) # now, this edge is available for caugi graphs: cg <- caugi(A %-->% B, B %<--% C, class = "DAG") # reset the registry to default reset_caugi_registry()# first, for reproducability, we reset the registry to default reset_caugi_registry() # create a new registry reg <- caugi_registry() # register an edge register_caugi_edge( glyph = "<--", tail_mark = "arrow", head_mark = "tail", class = "directed", symmetric = FALSE ) # now, this edge is available for caugi graphs: cg <- caugi(A %-->% B, B %<--% C, class = "DAG") # reset the registry to default reset_caugi_registry()
caugi edge registryThe caugi edge registry stores information about the different edge types
that can be used in caugi graphs. It maps edge glyphs (e.g., "-->",
"<->", "o->", etc.) to their specifications, including tail and head
marks, class, and symmetry. The registry allows for dynamic registration of
new edge types, enabling users to extend the set of supported edges in
caugi. It is implemented as a singleton, ensuring that there is a single
global instance of the registry throughout the R session.
caugi_registry() list_caugi_edges() reset_caugi_registry() seal_caugi_registry()caugi_registry() list_caugi_edges() reset_caugi_registry() seal_caugi_registry()
The intended use of the caugi registry is mostly for advanced users and
developers. The registry enables users who need to define their own custom
edge types in caugi directly. . It currently mostly supports the
representation of new edges, but for users that might want to represent
reverse edges, this preserves correctness of reason over these edges.
An edge_registry external pointer.
A data.table with columns glyph, tail, head, class, and
symmetric, where each row corresponds to a registered edge type.
caugi_registry(): Access the global edge registry, creating it if needed.
list_caugi_edges(): List all registered edge types in the global registry.
reset_caugi_registry(): Reset the global edge registry to its default state.
seal_caugi_registry(): Seal the global edge registry to prevent further
modifications.
Other registry:
register_caugi_edge()
# first, for reproducability, we reset the registry to default reset_caugi_registry() # create a new registry reg <- caugi_registry() # list registered edges list_caugi_edges() # register an edge register_caugi_edge( glyph = "<--", tail_mark = "arrow", head_mark = "tail", class = "directed", symmetric = FALSE ) # now, this edge is available for caugi graphs: list_caugi_edges() cg <- caugi(A %-->% B, B %<--% C, class = "DAG") # reset the registry to default reset_caugi_registry()# first, for reproducability, we reset the registry to default reset_caugi_registry() # create a new registry reg <- caugi_registry() # list registered edges list_caugi_edges() # register an edge register_caugi_edge( glyph = "<--", tail_mark = "arrow", head_mark = "tail", class = "directed", symmetric = FALSE ) # now, this edge is available for caugi graphs: list_caugi_edges() cg <- caugi(A %-->% B, B %<--% C, class = "DAG") # reset the registry to default reset_caugi_registry()
Check if two caugi objects have the same nodes.
same_nodes(cg1, cg2, throw_error = FALSE)same_nodes(cg1, cg2, throw_error = FALSE)
cg1 |
A |
cg2 |
A |
throw_error |
Logical; if |
A logical indicating if the two graphs have the same nodes.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
spouses(),
subgraph(),
topological_sort()
cg1 <- caugi( A %-->% B, class = "DAG" ) cg2 <- caugi( A %-->% B + C, class = "DAG" ) same_nodes(cg1, cg2) # FALSEcg1 <- caugi( A %-->% B, class = "DAG" ) cg2 <- caugi( A %-->% B + C, class = "DAG" ) same_nodes(cg1, cg2) # FALSE
Compute the Structural Hamming Distance (SHD) between two graphs.
shd(cg1, cg2, normalized = FALSE)shd(cg1, cg2, normalized = FALSE)
cg1 |
A |
cg2 |
A |
normalized |
Logical; if |
An integer representing the Hamming Distance between the two graphs,
if normalized = FALSE, or a numeric between 0 and 1 if normalized = TRUE.
cg1 <- caugi(A %-->% B %-->% C, D %-->% C, class = "DAG") cg2 <- caugi(A %-->% B %-->% C, D %---% C, class = "PDAG") shd(cg1, cg2) # 1cg1 <- caugi(A %-->% B %-->% C, D %-->% C, class = "DAG") cg2 <- caugi(A %-->% B %-->% C, D %---% C, class = "PDAG") shd(cg1, cg2) # 1
caugi DAG.Simulate data from a caugi object of class DAG using a
linear structural equation model (SEM). As standard, the data is
simulated from a DAG, where each node is generated as a linear combination
of its parents plus Gaussian noise, following the topological order of the
graph. Nodes without custom equations are simulated using auto-generated
linear Gaussian relationships.
simulate_data( cg, n, ..., standardize = TRUE, coef_range = c(0.1, 0.9), error_sd = 1, seed = NULL )simulate_data( cg, n, ..., standardize = TRUE, coef_range = c(0.1, 0.9), error_sd = 1, seed = NULL )
cg |
A |
n |
Integer; number of observations to simulate. |
... |
Named expressions for custom structural equations. Names must
match node names in the graph. Expressions can reference parent node names
and the variable |
standardize |
Logical; if |
coef_range |
Numeric vector of length 2; range for random edge
coefficients that will be sampled uniformly. Default is |
error_sd |
Numeric; standard deviation for error terms in
auto-generated equations. Default is |
seed |
Optional integer; random seed for reproducibility. |
A data.frame with n rows and one column per node, ordered
according to the node order in the graph.
Other simulation functions:
generate_graph()
cg <- caugi(A %-->% B, B %-->% C, A %-->% C, class = "DAG") # Fully automatic simulation df <- simulate_data(cg, n = 100) # With standardization df <- simulate_data(cg, n = 100, standardize = TRUE) # Custom equations for some nodes df <- simulate_data(cg, n = 100, A = rnorm(n, mean = 10, sd = 2), B = 0.5 * A + rnorm(n, sd = 0.5) ) # Reproducible simulation df <- simulate_data(cg, n = 100, seed = 42)cg <- caugi(A %-->% B, B %-->% C, A %-->% C, class = "DAG") # Fully automatic simulation df <- simulate_data(cg, n = 100) # With standardization df <- simulate_data(cg, n = 100, standardize = TRUE) # Custom equations for some nodes df <- simulate_data(cg, n = 100, A = rnorm(n, mean = 10, sd = 2), B = 0.5 * A + rnorm(n, sd = 0.5) ) # Reproducible simulation df <- simulate_data(cg, n = 100, seed = 42)
The skeleton of a graph is obtained by replacing all directed edges with undirected edges.
skeleton(cg)skeleton(cg)
cg |
A |
This changes the graph from any class to an Undirected Graph (UG), also known as a Markov Graph.
A caugi object representing the skeleton of the graph (UG).
Other operations:
condition_marginalize(),
dag_from_pdag(),
exogenize(),
latent_project(),
meek_closure(),
moralize(),
mutate_caugi(),
normalize_latent_structure()
cg <- caugi(A %-->% B, class = "DAG") skeleton(cg) # A --- Bcg <- caugi(A %-->% B, class = "DAG") skeleton(cg) # A --- B
Get nodes connected via bidirected edges in an ADMG.
spouses(cg, nodes = NULL, index = NULL)spouses(cg, nodes = NULL, index = NULL)
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
Either a character vector of node names (if a single node is requested) or a list of character vectors (if multiple nodes are requested).
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
subgraph(),
topological_sort()
cg <- caugi( A %-->% B, A %<->% C, B %<->% C, class = "ADMG" ) spouses(cg, "A") # "C" spouses(cg, "C") # c("A", "B")cg <- caugi( A %-->% B, A %<->% C, B %<->% C, class = "ADMG" ) spouses(cg, "A") # "C" spouses(cg, "C") # c("A", "B")
Get the induced subgraph
subgraph(cg, nodes = NULL, index = NULL)subgraph(cg, nodes = NULL, index = NULL)
cg |
A |
nodes |
A character vector of node names. |
index |
A vector of node indexes. |
A new caugi that is a subgraph of the selected nodes.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
topological_sort()
cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) sub_cg <- subgraph(cg, c("B", "C")) cg2 <- caugi(B %-->% C, class = "DAG") all(nodes(sub_cg) == nodes(cg2)) # TRUE all(edges(sub_cg) == edges(cg2)) # TRUEcg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) sub_cg <- subgraph(cg, c("B", "C")) cg2 <- caugi(B %-->% C, class = "DAG") all(nodes(sub_cg) == nodes(cg2)) # TRUE all(edges(sub_cg) == edges(cg2)) # TRUE
Converts a caugi graph to the Graphviz DOT format as a string. The DOT format can be used with Graphviz tools for visualization and analysis.
to_dot(x, graph_attrs = list(), node_attrs = list(), edge_attrs = list())to_dot(x, graph_attrs = list(), node_attrs = list(), edge_attrs = list())
x |
A |
graph_attrs |
Named list of graph attributes (e.g.,
|
node_attrs |
Named list of default node attributes. |
edge_attrs |
Named list of default edge attributes. |
The function handles different edge types:
Directed edges (-->) use -> in DOT
Undirected edges (---) use -- in DOT (or -> with dir=none in digraphs)
Bidirected edges (<->) use -> with [dir=both] attribute
Partial edges (o->) use -> with [arrowtail=odot, dir=both] attribute
A caugi_dot object containing the DOT representation.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Get DOT string dot <- to_dot(cg) dot@content # With custom attributes dot <- to_dot( cg, graph_attrs = list(rankdir = "LR"), node_attrs = list(shape = "box") )cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Get DOT string dot <- to_dot(cg) dot@content # With custom attributes dot <- to_dot( cg, graph_attrs = list(rankdir = "LR"), node_attrs = list(shape = "box") )
Converts a caugi graph to the GraphML XML format as a string. GraphML is widely supported by graph analysis tools and libraries.
to_graphml(x)to_graphml(x)
x |
A |
The GraphML export includes:
Node IDs and labels
Edge types stored as a custom edge_type attribute
Graph class stored as a graph-level attribute
Edge types are encoded using the caugi DSL operators (e.g., "–>", "<->"). This allows for perfect round-trip conversion back to caugi.
A caugi_graphml object containing the GraphML representation.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Get GraphML string graphml <- to_graphml(cg) cat(graphml@content) # Write to file ## Not run: write_graphml(cg, "graph.graphml") ## End(Not run)cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Get GraphML string graphml <- to_graphml(cg) cat(graphml@content) # Write to file ## Not run: write_graphml(cg, "graph.graphml") ## End(Not run)
Converts a caugi graph to the Mermaid flowchart format as a string. Mermaid diagrams can be rendered in Quarto, R Markdown, GitHub, and many other platforms.
to_mermaid(x, direction = "TD")to_mermaid(x, direction = "TD")
x |
A |
direction |
Graph direction: "TB" (top-bottom), "TD" (top-down), "BT" (bottom-top), "LR" (left-right), or "RL" (right-left). Default is "TD". |
The function handles different edge types:
Directed edges (-->) use --> in Mermaid
Undirected edges (---) use --- in Mermaid
Bidirected edges (<->) use <--> in Mermaid
Partial edges (o->) use o--> in Mermaid (circle end)
Node names are automatically escaped if they contain special characters.
A caugi_mermaid object containing the Mermaid representation.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
write_caugi(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Get Mermaid string mmd <- to_mermaid(cg) mmd@content # With custom direction mmd <- to_mermaid(cg, direction = "LR")cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Get Mermaid string mmd <- to_mermaid(cg) mmd@content # With custom direction mmd <- to_mermaid(cg, direction = "LR")
Returns a topological ordering of the nodes in a DAG. For every directed edge u -> v in the graph, u will appear before v in the returned ordering.
topological_sort(cg)topological_sort(cg)
cg |
A |
A character vector of node names in topological order.
Other queries:
ancestors(),
anteriors(),
children(),
descendants(),
districts(),
edge_types(),
edges(),
exogenous(),
is_acyclic(),
is_admg(),
is_ag(),
is_caugi(),
is_cpdag(),
is_dag(),
is_empty_caugi(),
is_mag(),
is_mpdag(),
is_pdag(),
is_simple(),
is_ug(),
m_separated(),
markov_blanket(),
neighbors(),
nodes(),
parents(),
posteriors(),
same_nodes(),
spouses(),
subgraph()
# Simple DAG: A -> B -> C cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) topological_sort(cg) # Returns c("A", "B", "C") or equivalent valid ordering # DAG with multiple valid orderings cg2 <- caugi( A %-->% C, B %-->% C, class = "DAG" ) # Could return c("A", "B", "C") or c("B", "A", "C") topological_sort(cg2)# Simple DAG: A -> B -> C cg <- caugi( A %-->% B, B %-->% C, class = "DAG" ) topological_sort(cg) # Returns c("A", "B", "C") or equivalent valid ordering # DAG with multiple valid orderings cg2 <- caugi( A %-->% C, B %-->% C, class = "DAG" ) # Could return c("A", "B", "C") or c("B", "A", "C") topological_sort(cg2)
Writes a caugi graph to a file in the native caugi JSON format. This format is designed for reproducibility, caching, and sharing caugi graphs across R sessions.
write_caugi(x, path, comment = NULL, tags = NULL)write_caugi(x, path, comment = NULL, tags = NULL)
x |
A |
path |
Character string specifying the file path. |
comment |
Optional character string with a comment about the graph. |
tags |
Optional character vector of tags for categorizing the graph. |
The caugi format is a versioned JSON schema that captures:
Graph structure (nodes and edges with their types)
Graph class (DAG, PDAG, ADMG, UG, etc.)
Optional metadata (comments and tags)
Edge types are encoded using their DSL operators (e.g., "-->", "<->", "--").
For a complete guide to the format, see vignette("serialization", package = "caugi").
The formal JSON Schema is available at:
https://caugi.org/schemas/caugi-v1.schema.json
Invisibly returns the input x.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_dot(),
write_graphml(),
write_mermaid()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Write to file tmp <- tempfile(fileext = ".caugi.json") write_caugi(cg, tmp, comment = "Example DAG") # Read back cg2 <- read_caugi(tmp) identical(edges(cg), edges(cg2)) # Clean up unlink(tmp)cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) # Write to file tmp <- tempfile(fileext = ".caugi.json") write_caugi(cg, tmp, comment = "Example DAG") # Read back cg2 <- read_caugi(tmp) identical(edges(cg), edges(cg2)) # Clean up unlink(tmp)
Writes a caugi graph to a file in Graphviz DOT format.
write_dot(x, file, ...)write_dot(x, file, ...)
x |
A |
file |
Path to output file. |
... |
Additional arguments passed to |
Invisibly returns the path to the file.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_graphml(),
write_mermaid()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) ## Not run: # Write to file write_dot(cg, "graph.dot") # With custom attributes write_dot( cg, "graph.dot", graph_attrs = list(rankdir = "LR") ) ## End(Not run)cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) ## Not run: # Write to file write_dot(cg, "graph.dot") # With custom attributes write_dot( cg, "graph.dot", graph_attrs = list(rankdir = "LR") ) ## End(Not run)
Exports a caugi graph to a GraphML file.
write_graphml(x, path)write_graphml(x, path)
x |
A |
path |
File path for the output GraphML file. |
Invisibly returns NULL. Called for side effects.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_mermaid()
cg <- caugi(A %-->% B + C, class = "DAG") tmp <- tempfile(fileext = ".graphml") write_graphml(cg, tmp) # Read it back cg2 <- read_graphml(tmp) # Clean up unlink(tmp)cg <- caugi(A %-->% B + C, class = "DAG") tmp <- tempfile(fileext = ".graphml") write_graphml(cg, tmp) # Read it back cg2 <- read_graphml(tmp) # Clean up unlink(tmp)
Writes a caugi graph to a file in Mermaid format.
write_mermaid(x, file, ...)write_mermaid(x, file, ...)
x |
A |
file |
Path to output file. |
... |
Additional arguments passed to |
Invisibly returns the path to the file.
Other export:
caugi_deserialize(),
caugi_dot(),
caugi_export(),
caugi_graphml(),
caugi_mermaid(),
caugi_serialize(),
export-classes,
format-caugi,
format-dot,
format-graphml,
format-mermaid,
knit_print.caugi_export,
read_caugi(),
read_graphml(),
to_dot(),
to_graphml(),
to_mermaid(),
write_caugi(),
write_dot(),
write_graphml()
cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) ## Not run: # Write to file write_mermaid(cg, "graph.mmd") # With custom direction write_mermaid(cg, "graph.mmd", direction = "LR") ## End(Not run)cg <- caugi( A %-->% B + C, B %-->% D, C %-->% D, class = "DAG" ) ## Not run: # Write to file write_mermaid(cg, "graph.mmd") # With custom direction write_mermaid(cg, "graph.mmd", direction = "LR") ## End(Not run)