Nothing
##=============================================================================
#' Plot a \code{gg_udependent} variable dependency graph
#'
#' Draws the dependency graph held in a \code{gg_udependent} object as a
#' ggraph network. Node colour marks whether a variable made the signal
#' set, and the width and opacity of an edge tell you how strong the
#' dependency between its two variables is.
#'
#' @section Reading the network:
#' Each node is a variable; each edge is a cross-variable dependency
#' that cleared the threshold passed to \code{gg_udependent}. The
#' Fruchterman-Reingold layout (the default) places mutually connected
#' variables near each other, so the picture tends to show hubs and
#' the clusters around them rather than a tidy ring. The eye usually
#' goes first to the largest blue node: a variable that is both in
#' the signal set and connects to many others is a hub of the
#' dependency structure. Edges with wider, more opaque strokes are
#' stronger dependencies; thin, faint edges sit near the threshold and
#' are the ones that would disappear first if you raised it.
#'
#' Grey, low-degree nodes are the ones UVarPro thinks are not
#' contributing much to the structure. (Truly isolated nodes are
#' dropped by `gg_udependent()` before the graph is drawn; what you
#' see is the connected component.) A cluster of mutually
#' connected variables is worth checking for redundancy; they may be
#' several views of the same underlying quantity.
#'
#' @section What this tells you:
#' Use the figure to pick a working set of variables: the hubs and
#' their immediate neighbours are the candidates UVarPro flags as
#' carrying structure. If a cluster of high-degree variables looks
#' like it might be measuring the same thing, that is a cue to look at
#' their pairwise correlations or fit them as a block rather than
#' individually. The threshold and layout are recorded in the caption
#' so a different choice is easy to spot in a later figure.
#'
#' @param x A \code{gg_udependent} object from \code{\link{gg_udependent}}.
#' @param layout Character; the igraph/ggraph layout algorithm. Common
#' choices are \code{"fr"} (Fruchterman-Reingold, the default),
#' \code{"kk"} (Kamada-Kawai), \code{"stress"}, \code{"circle"}, and
#' \code{"grid"}.
#' @param ... Not currently used.
#'
#' @details
#' This plot needs the \pkg{ggraph} package, which is in \code{Suggests}
#' rather than installed for you. If it is missing, run
#' \code{install.packages("ggraph")}.
#'
#' A signal variable (\code{selected = TRUE}) gets a blue node
#' (\code{#4e8fcd}); the rest are grey (\code{#888888}). Node size grows
#' with degree. Edge width and opacity both grow with the raw dependency
#' weight \code{I[i,j]}.
#'
#' @return A \code{ggplot} object (built via ggraph).
#'
#' @seealso \code{\link{gg_udependent}}
#'
#' @examples
#' \donttest{
#' if (requireNamespace("ggraph", quietly = TRUE)) {
#' set.seed(42)
#' uv <- varPro::uvarpro(iris[, -5], ntree = 50)
#' plot(gg_udependent(uv))
#' }
#' }
#'
#' @name plot.gg_udependent
#' @importFrom ggplot2 aes labs scale_color_manual theme_void
#' @importFrom igraph vertex_attr V edge_attr as_data_frame E
#' @export
plot.gg_udependent <- function(x, layout = "fr", ...) {
prov <- attr(x, "provenance")
if (is.null(x$graph) || nrow(x$edges) == 0L) {
stop("gg_udependent: no edges to plot. ",
"Lower threshold (currently ", prov$threshold,
") to detect dependencies.",
call. = FALSE)
}
if (!requireNamespace("ggraph", quietly = TRUE)) {
stop("Install the 'ggraph' package to use plot.gg_udependent(): ",
"install.packages('ggraph')", call. = FALSE)
}
## Ensure vertex attributes are present (guard against old objects) --------
if (is.null(igraph::vertex_attr(x$graph, "selected"))) {
sel <- x$nodes$selected[match(igraph::V(x$graph)$name,
as.character(x$nodes$variable))]
igraph::V(x$graph)$selected <- sel
}
if (is.null(igraph::vertex_attr(x$graph, "degree"))) {
deg <- x$nodes$degree[match(igraph::V(x$graph)$name,
as.character(x$nodes$variable))]
igraph::V(x$graph)$degree <- deg
}
## Edge-weight backfill: guard for legacy objects saved before edge weights
## were stored on the igraph. Order-insensitive for undirected graphs.
if (is.null(igraph::edge_attr(x$graph, "weight"))) {
prov_d <- isTRUE(attr(x, "provenance")$directed)
edge_list <- igraph::as_data_frame(x$graph, what = "edges")
if (prov_d) {
idx <- match(paste(edge_list$from, edge_list$to),
paste(x$edges$variable_from, x$edges$variable_to))
} else {
key_g <- paste(pmin(edge_list$from, edge_list$to),
pmax(edge_list$from, edge_list$to))
key_e <- paste(pmin(x$edges$variable_from, x$edges$variable_to),
pmax(x$edges$variable_from, x$edges$variable_to))
idx <- match(key_g, key_e)
}
igraph::E(x$graph)$weight <- x$edges$weight[idx]
}
ggraph::ggraph(x$graph, layout = layout) +
ggraph::geom_edge_link(
ggplot2::aes(width = .data[["weight"]],
alpha = .data[["weight"]]),
color = "#4e8fcd"
) +
ggraph::geom_node_point(
ggplot2::aes(color = factor(.data[["selected"]]),
size = .data[["degree"]])
) +
ggraph::geom_node_label(
ggplot2::aes(label = .data[["name"]]),
size = 3, show.legend = FALSE
) +
ggplot2::scale_color_manual(
values = c("TRUE" = "#4e8fcd", "FALSE" = "#888888"),
guide = "none"
) +
ggraph::scale_edge_width(range = c(0.5, 2.5), guide = "none") +
ggraph::scale_edge_alpha(range = c(0.3, 1.0), guide = "none") +
ggplot2::labs(
size = "Degree",
caption = paste0("Dependency threshold: ", prov$threshold,
". Layout: ", layout, ".")
) +
ggplot2::theme_void()
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.