Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bf3f351
Set `format_special=FALSE` by default
jrgant Nov 29, 2025
8eefd02
Cosmetic
jrgant Nov 30, 2025
f4cb169
Update function name and documentation
jrgant Nov 30, 2025
df24eb6
Add more informative theme error
jrgant Nov 30, 2025
1444d3e
Set conditioned shape to "rectangle"
jrgant Nov 30, 2025
e5ff6b6
Merge remote-tracking branch 'origin/master' into v1.0.0
jrgant Nov 30, 2025
def5744
Fix logic in choosing returned object
jrgant Dec 1, 2025
66b6c58
Add global options
jrgant Dec 1, 2025
c9d3bb4
Add basic node and edge modification via alpha_ids
jrgant Dec 1, 2025
79722b4
Cosmetic
jrgant Dec 2, 2025
6e2929d
Add documentation for get_numds()
jrgant Dec 2, 2025
440f3fa
Add documentation for get_numids()
jrgant Dec 2, 2025
5242d3a
Merge remote-tracking branch 'origin/v1.0.0' into v1.0.0
jrgant Dec 26, 2025
c0c68f3
Tweak comment
jrgant Dec 29, 2025
6886114
Store theme and conditioned info to DAG object
jrgant Dec 29, 2025
5f1f9ad
Get basic "pearl" theme working
jrgant Dec 29, 2025
e919164
Add cleanup_existing_themes()
jrgant Dec 29, 2025
268c137
Save theme name; tweak 'pearl'
jrgant Dec 29, 2025
52efec3
Add global options for 'pearl' theme
jrgant Dec 29, 2025
7867d84
Return graph_out
jrgant Dec 29, 2025
30322d4
Use explicit argument names for ...
jrgant Dec 29, 2025
fe9374d
Cosmetic
jrgant Dec 29, 2025
276d247
New theme opts and cleanup conditioned processing
jrgant Dec 29, 2025
08157a8
Use underscore for rdname
jrgant Dec 29, 2025
5d1832b
Update parameter options and documentation
jrgant Dec 30, 2025
a5238ca
Fix bad parameter and set node attributes
jrgant Dec 30, 2025
81786ac
Add arrowsize for base theme; unset head/tailport
jrgant Dec 31, 2025
ecfc901
Rework default theming
jrgant Dec 31, 2025
aef6a99
Fix problem with specifying attributes
jrgant Dec 31, 2025
6fab182
Base theme opts provide shared defaults
jrgant Dec 31, 2025
a3c1e1a
Add option to select arrowhead shape
jrgant Dec 31, 2025
b398c0d
Revert to dots to pass values to set functions
jrgant Dec 31, 2025
ff537c8
Tweak and add separate options for SWIGs
jrgant Dec 31, 2025
4354297
Add docs for missing arrow property parameters
jrgant Apr 20, 2026
ad899b4
Remove 'messaging' package
jrgant Apr 20, 2026
294e17f
Add 'id' to global variables
jrgant Apr 20, 2026
7e8ebac
Add 'values' to global variables
jrgant Apr 20, 2026
c67a7cc
Fix adjustment set example
jrgant Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Imports:
dagitty (>= 0.3.4),
DiagrammeR (>= 1.0.11),
dplyr (>= 1.1.4),
messaging (>= 0.1.0),
purrr (>= 1.1.0),
rlang (>= 1.1.6),
stringr (>= 1.5.1),
Expand Down
8 changes: 8 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
# Generated by roxygen2: do not edit by hand

export(cleanup_existing_theme)
export(get_conditioned_nodes)
export(parse_edges)
export(parse_edgestring)
export(parse_nodes)
export(qd_adjustment_sets)
export(qd_dag)
export(qd_save)
export(qd_select_edges)
export(qd_select_nodes)
export(qd_set_edge_attrs)
export(qd_set_node_attrs)
export(qd_swig)
export(qd_themes)
export(qd_todagitty)
export(select_edges_by_node_alpha_id)
export(select_nodes_by_alpha_id)
export(sep_opts)
export(theme_qd_base)
export(theme_qd_circles)
Expand Down
78 changes: 78 additions & 0 deletions R/graph_operations.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#' Graph operations
#'
#' @param graph_obj A `quickdag` object output by [qd_dag()] or [qd_swig()].
#' @param alpha_ids A vector of alphanumeric node IDs upon which to operate.
#' @param ... Passed to [DiagrammeR::set_node_attrs()] or [DiagrammeR::set_edge_attrs()]
#' argument `node_attr` or `edge_attr`, respectively.
#' [DiagrammeR::set_edge_attrs()] argument of the same name.
#' @param from_alpha A vector of alphanumeric source node IDs.
#' @param to_alpha A vector of alphanumeric destination node IDs.
#' @param set_op Passed to the `set_op` argument of [DiagrammeR::select_nodes_by_id()]
#' or [DiagrammeR::select_edges_by_node_id()]. Defaults to "union".
#'
#' @rdname graph_operations
#' @export
qd_set_node_attrs <- function(graph_obj, ..., alpha_ids) {
numids <- get_numids(graph_obj, alpha_ids)
graph_out <- DiagrammeR::set_node_attrs(graph_obj,
...,
values = values,
nodes = numids)
graph_out
}

#' @rdname graph_operations
#' @export
qd_set_edge_attrs <- function(graph_obj, ...,
from_alpha = NULL, to_alpha = NULL) {
from_numids <- NULL
to_numids <- NULL
if (!is.null(from_alpha)) {
from_numids <- get_numids(graph_obj, from_alpha)
}
if (!is.null(to_alpha)) {
to_numids <- get_numids(graph_obj, to_alpha)
}
graph_out <- DiagrammeR::set_edge_attrs(graph_obj,
...,
values = values,
from = from_numids,
to = to_numids)
graph_out
}

#' @rdname graph_operations
#' @export
select_nodes_by_alpha_id <- function(graph_obj, alpha_ids, set_op = "union") {
numids <- get_numids(graph_obj, alpha_ids)
graph_out <- DiagrammeR::select_nodes_by_id(graph_obj,
nodes = numids,
set_op = set_op)
graph_out
}

#' @rdname graph_operations
#' @export
qd_select_nodes <- select_nodes_by_alpha_id

#' @rdname graph_operations
#' @export
select_edges_by_node_alpha_id <- function(graph_obj, alpha_ids, set_op = "union") {
numids <- get_numids(graph_obj, alpha_ids)
graph_out <- DiagrammeR::select_edges_by_node_id(graph_obj,
nodes = numids,
set_op = set_op)
graph_out
}

#' @rdname graph_operations
#' @export
qd_select_edges <- select_edges_by_node_alpha_id

#' Retrieves numeric IDs given alphanumeric IDs
#' @inheritParams qd_set_node_attrs
get_numids <- function(graph_obj, alpha_ids) {
graph_obj$nodes_df |>
dplyr::filter(alpha_id %in% alpha_ids) |>
dplyr::pull(id)
}
6 changes: 3 additions & 3 deletions R/parse.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' @title Parse nodes
#' @inheritParams qd_dag
#' @rdname node-parsing
#' @rdname node_parsing
#' @export
parse_nodes <- function(edgelist) {
nodes <- unlist(lapply(edgelist,
Expand All @@ -12,7 +12,7 @@ parse_nodes <- function(edgelist) {

#' @title Parse edges in a graph specification
#' @param edgestring A single string containing some set of node-edge relationships
#' @rdname edge-parsing
#' @rdname edge_parsing
#' @export
parse_edgestring <- function(edgestring) {
edgepat <- "\\<\\-\\>|\\-\\>|\\<\\-"
Expand Down Expand Up @@ -52,7 +52,7 @@ parse_edgestring <- function(edgestring) {
Reduce(rbind, edge_mini_dfs)
}

#' @rdname edge-parsing
#' @rdname edge_parsing
#' @inheritParams qd_dag
#' @export
parse_edges <- function(edgelist) {
Expand Down
12 changes: 7 additions & 5 deletions R/qd_dag.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#' @param edge_aes_opts A list feeding aesthetic options for edges to
#' [DiagrammeR::edge_aes()]. Defaults to empty list.
#' @param format_special Render numeric elements in an alphanumeric `alpha_id` as
#' subcripts. Defaults to `TRUE`.
#' subcripts. Defaults to `FALSE`.
#' @param verbose Indicate whether to print node and edge dataframes to the console.
#' See Details below. Defaults to `TRUE`.
#' @param check_dag Logical. Check whether the graph conforms to the rules of DAGs.
Expand All @@ -31,7 +31,7 @@
#' edges <- c("A -> { B C } <- L",
#' "B -> C")
#'
#' # make a DAG object and render the graph using the default theme
#' # Make a DAG object and render the graph using the default theme
#' g.obj <- qd_dag(edges)
#' DiagrammeR::render_graph(g.obj)
#'
Expand All @@ -51,8 +51,11 @@
#'
qd_dag <- function(edgelist, node_labs = NULL,
node_aes_opts = list(), edge_aes_opts = list(),
format_special = TRUE,
verbose = FALSE, check_dag = TRUE, theme = "base", ...) {
format_special = getOption("quickdag.format_special"),
verbose = getOption("quickdag.verbose"),
check_dag = getOption("quickdag.check_dag"),
theme = getOption("quickdag.theme"),
...) {

# Identify Nodes --------------------------------------------------------
## extract unique nodes, sort in ascending order
Expand Down Expand Up @@ -171,5 +174,4 @@ qd_dag <- function(edgelist, node_labs = NULL,

class(graph) <- c("quickdag", "dgr_graph")
graph

}
3 changes: 2 additions & 1 deletion R/qd_save.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
#'
#' # clean up temporary directory
#' file.remove(file)
qd_save <- function(graph, file_name, ..., embed = FALSE, kg = NULL) {
qd_save <- function(graph, file_name, ...,
embed = getOption("quickdag.embed"), kg = NULL) {
DiagrammeR::export_graph(graph = graph, file_name = file_name, ...)

if (embed == TRUE) {
Expand Down
4 changes: 2 additions & 2 deletions R/qd_swig.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
qd_swig <- function(graph_obj,
fixed_nodes,
custom_values = NULL,
fixed_sep = "vlin",
sep_point_size = 15) {
fixed_sep = getOption("quickdag.swig_fixedsep"),
sep_point_size = getOption("quickdag.swig_sepsize")) {

ndf <- DiagrammeR::get_node_df(graph_obj)
ndf$fixed <- with(ndf, ifelse(alpha_id %in% fixed_nodes, TRUE, FALSE))
Expand Down
52 changes: 33 additions & 19 deletions R/qd_todagitty.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,58 @@
#' @description
#' Format an edgelist and send it to dagitty to identify variable adjustment sets.
#'
#' @param edgelist A vector of edge relationships. Must be strictly organized (see
#' example for format).
#' @param edgelist A vector of edge relationships.
#' @param diagram_type Character identifying the diagram type. Defaults to "dag", but
#' user can specify another graph type (see dagitty documentation).
#' user can specify another graph type (see [dagitty::adjustmentSets()]).
#' @param showplot Logical indicating whether to produce a dagitty plot. Defaults to
#' `FALSE`.
#' @param exposure Character. Specify exposure of interest. (Required)
#' @param outcome Character. Specifiy outcome of interest. (Required)
#' @param ... Pass arguments to [dagitty::adjustmentSets()]. See dagitty documentation
#' for options.
#' @param ... Pass arguments to [dagitty::adjustmentSets()].
#'
#' @details
#' The `exposure` and `outcome` options map to dagitty functions of the same name.
#' The `exposure` and `outcome` options map to dagitty parameters of the same name.
#'
#' [qd_todagitty()] remains an alias for [qd_adjustment_sets()] to avoid breaking
#' existing scripts, as it was the original name of this function.
#'
#' @rdname qd_adjustment_sets
#' @export
#' @examples
#' # feed an edgelist to qd_adjustment_sets()
#' edges <- c("A -> { B C D }",
#' "B -> C",
#' "E -> { B C }")
#' # must pass exposure and outcome arguments to dagitty::adjustmentSets()
#' qd_todagitty(edges, exposure = "A", outcome = "C")
#' qd_todagitty(edges, exposure = "A", outcome = "C", type = "minimal")
qd_todagitty <- function(edgelist, diagram_type = "dag", showplot = FALSE,
exposure, outcome,
...) {
#' "E -> { B C }",
#' "Y <- L -> A")
#' qd_adjustment_sets(edges, exposure = "A", outcome = "C")
#' qd_adjustment_sets(edges, exposure = "A", outcome = "C", type = "minimal")
#'
#' # if you've already created a qd_dag() object
#' dag <- qd_dag(edges)
#' qd_adjustment_sets(dag$qd_edgelist, exposure = "A", outcome = "Y")
qd_adjustment_sets <- function(edgelist, diagram_type = "dag", showplot = FALSE,
exposure, outcome,
...) {

dagitty_obj <- dagitty::dagitty(paste(diagram_type, "{",
paste(edgelist, collapse = "; "),
"}"),
layout = TRUE)
dagitty_obj <- dagitty::dagitty(
paste(diagram_type, "{", paste(edgelist, collapse = "; "), "}"),
layout = TRUE
)

## optional to show dagitty plot
if (showplot) {
plot(dagitty_obj)
}

## use dagitty's algorithm to identify adjustment sets
sets <- dagitty::adjustmentSets(dagitty_obj, exposure = exposure,
outcome = outcome, ...)
sets <- dagitty::adjustmentSets(dagitty_obj,
exposure = exposure,
outcome = outcome,
...)
return(sets)
}


#' @rdname qd_adjustment_sets
#' @export
qd_todagitty <- qd_adjustment_sets
8 changes: 4 additions & 4 deletions R/sep_opts.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ sep_opts <- function(entity = NULL, table = FALSE) {
)
}

if (entity %in% names(defopts)) {
if (is.null(entity)) {
defopts
} else if (entity %in% names(defopts)) {
defopts[names(defopts) == entity]
} else if (!is.null(entity)) {
entity
} else {
defopts
entity
}
}
Loading
Loading