RedeR is an R-based package combined with a stand-alone Java application for interactive visualization and manipulation of nested networks. Graph, node, and edge attributes are set either using graphical or command-line methods following igraph syntax rules. The RedeR/R package sets all details to initialize the R-to-Java interface, which uses an interactive force-directed layout algorithm, adjusting the graph layout to the hierarchical levels of a nested network. Supporting information is available from Castro et al. (2016).
RedeR 3.2.0
RedeR is an R-based package combined with a Java application for network analysis and visualization. RedeR is designed to deal with three key challenges in network analysis. Firstly, biological networks are modular and hierarchical, so network visualization needs to take advantage of such structural features. Secondly, network analysis relies on statistical methods, many of which are already available in resources like CRAN or Bioconductor. Thirdly, in larger networks user input is needed to focus the view of the network on the biologically relevant parts, rather than relying on an automatic layout function. The graphical user interface is depicted in Figure 1.
The RedeR/R package sets all details to initialize the R-to-Java interface. Next, the startRedeR()
function will launch the RedeR application (Figure 1), initializing the R-to-Java interface:
Note that RedeR >=2.0.0 is designed to run on Java>=11 (see system requirements).
The addGraphToRedeR()
function displays igraph objects in the RedeR application. The following snippet will display the gtoy1
graph in RedeR, using the layout_with_kk()
function to set the network layout (Figure 2):
## Warning: `graph.lattice()` was deprecated in igraph 2.1.0.
## ℹ Please use `make_lattice()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
In the reverse process, graphs are transferred from the application to R using the getGraphFromRedeR()
function:
## IGRAPH 68e19d6 U--- 0 0 --
The addGraphToRedeR()
method is also used to nest graphs into containers when setting isNested = TRUE
. Next, the graphs g1
and g2
are nested into containers and then displayed in the RedeR application.
#--- Generate two scale-free graphs
g1 <- sample_pa(7)
g2 <- sample_pa(5)
#--- Set names to graph vertices
V(g1)$name <- paste("m",1:7,sep="")
V(g2)$name <- paste("n",1:5,sep="")
#--- Nest graphs into containers
addGraphToRedeR(g=g1, isNested=TRUE, gcoord=c(30,30), gscale=50)
addGraphToRedeR(g=g2, isNested=TRUE, gcoord=c(70,70), gscale=40)
In this case, g1
and g2
are nested into containers N1 and N2, respectively (Figure 3). Each subgraph will retain the network structure, allowing access to individual nodes and edges in subsequent jobs. For example, the following snippet selects all nodes in container N2 and then retrieves the corresponding subgraph.
#--- Select nodes within a container
selectNodes(nodes="N2")
#--- Get nodes from 'N2'
getGraphFromRedeR(status="selected")
## IGRAPH 741f6e7 U--- 0 0 --
## + edges from 741f6e7:
The following snippet generates a scale-free graph using igraph's sample_pa()
function and then displays the network in RedeR.
#--- Generate a larger scale-free graph
g1 <- sample_pa(100, directed=FALSE)
#--- Set names to igraph vertices
V(g1)$name <- paste0("V",1:vcount(g1))
#--- Check attributes in the 'g1' graph
summary(g1)
## IGRAPH 1c5efd1 UN-- 100 99 -- Barabasi graph
## + attr: name (g/c), power (g/n), m (g/n), zero.appeal (g/n), algorithm
## | (g/c), name (v/c)
Next, the relaxRedeR()
function starts RedeR's interactive force-directed layout algorithm, which will arrange the network as in Figure 4A. The layout algorithm has 9 parameters (p1
to p9
), set either in the relaxRedeR()
function or in the interactive application. These parameters control the layout algorithm by adjusting the relaxing process to the hierarchical levels of the network.
RedeR attributes can be set either using the graphical user interface or the command-line interface. When using command-line attributes, these must follow igraph syntax rules and valid RedeR's attribute names. Graph attributes are set directly on a graph using igraph shortcuts, while node and edge attributes are set using igraph's V()
and E()
functions, respectivelly. For example:
#--- Set a new graph attribute in 'g1'
g1$bgcolor <- "white"
#--- Set new node attributes in 'g1'
V(g1)$nodeLineColor <- "skyblue"
V(g1)$nodeSize <- 50
#--- Set new edge attributes in 'g1'
E(g1)$edgeLineColor <- "skyblue"
E(g1)$edgeLineWidth <- 10
## IGRAPH 1c5efd1 UN-- 100 99 -- Barabasi graph
## + attr: name (g/c), power (g/n), m (g/n), zero.appeal (g/n), algorithm
## | (g/c), bgcolor (g/c), name (v/c), nodeLineColor (v/c), nodeSize
## | (v/n), edgeLineColor (e/c), edgeLineWidth (e/n)
Tables 1, 2, and 3 list all command-line attributes available for the current version (RedeR 3.2.0), including usage examples.
RedeR attribute | Description | Value | Usage example |
---|---|---|---|
bgcolor | Background color of the app panel | Single color, hexadecimal or name | g$bgcolor <- 'white' |
gscale | Graph expansion factor in the app panel | Single number in [0, 100] | g$gscale <- 75 |
zoom | Zoom scale applied to the app panel | Single number in [0, 100] | g$zoom <- 100 |
nestShape | Container shapes | 'ELLIPSE', 'RECTANGLE', 'ROUNDED_RECTANGLE', 'TRIANGLE', 'DIAMOND' | g$nestShape <- 'ELLIPSE' |
nestSize | Container size | Single number >=0 | g$nestSize <- 500 |
nestColor | Container color | Single color, hexadecimal or name | g$nestColor <- 'grey' |
nestLineType | Container line types | 'SOLID', 'DOTTED', 'DASHED', 'LONG_DASH' | g$nestLineType <- 'SOLID' |
nestLineWidth | Container line width | Single number >=0 | g$nestLineWidth <- 2 |
nestLineColor | Container line color | Single color, hexadecimal or name | g$nestLineColor <- 'grey' |
nestLabel | Label of the container | Single string | g$nestLabel <- 'a_name' |
nestLabelSize | Label size | Single number >=0 | g$nestLabelSize <- 24 |
nestLabelColor | Label color | Single color, hexadecimal or name | g$nestLabelColor <- 'grey20' |
nestLabelCoords | Label xy-coord, relative to container | Numeric vector with two numbers | g$nestLabelCoords <- c(x=0, y=0) |
RedeR attribute | Description | Value | Usage example |
---|---|---|---|
name | Node name | Character vector (unique IDs) | V(g)$name <- paste0('Node',1:vcount(g)) |
x | Node x-coordinate | Numeric vector in (-Inf, Inf) | V(g)$x <- runif(vcount(g)) |
y | Node y-coordinate | Numeric vector in (-Inf, Inf) | V(g)$y <- runif(vcount(g)) |
nodeShape | Node shapes | 'ELLIPSE', 'RECTANGLE', 'ROUNDED_RECTANGLE', 'TRIANGLE', 'DIAMOND' | V(g)$nodeShape <- 'ELLIPSE' |
nodeSize | Node size | Numeric vector >=0 | V(g)$nodeSize <- 20 |
nodeColor | Node color | Hexadecimal or color name | V(g)$nodeColor <- 'white' |
nodeLineWidth | Line width | Numeric vector >=0 | V(g)$nodeLineWidth <- 1 |
nodeLineColor | Line color | Hexadecimal or color name | V(g)$nodeLineColor <- 'grey' |
nodeLabel | Node label | Character vector | V(g)$nodeLabel <- V(g)$name |
nodeLabelSize | Label size | Numeric vector >=0 | V(g)$nodeLabelSize <- 12 |
nodeLabelColor | Label color | Hexadecimal or color name | V(g)$nodeLabelColor <- 'black' |
nodeBend | Node bend | Numeric vector in [0,100] | V(g)$nodeBend <- 50 |
nodeWeight | Node weight (not implemented) | Numeric vector >=0 | V(g)$nodeWeight <- 0 |
RedeR attribute | Description | Value | Usage example |
---|---|---|---|
edgeLineType | Line types | 'SOLID', 'DOTTED', 'DASHED', 'LONG_DASH' | E(g)$edgeLineType <- 'SOLID' |
edgeLineWidth | Line width | Numeric vector >=0 | E(g)$edgeLineWidth <- 1 |
edgeLineColor | Line color | Hexadecimal or color name | E(g)$edgeLineColor <- 'grey' |
arrowType | Arrows in directed graphs | Integer vector: -1, 0, 1 | E(g)$arrowType <- 1 |
arrowType | Arrows in undirected graphs | Integer vector: 0 (A-B), 1 (A-> B), -1 (A-| B), 2 (A <-B), -2 (A |-B), 3 (A <-> B), -3 (A |-| B), 4 (A |-> B), -4 (A <-| B) | E(g)$arrowType <- 0 |
arrowLength | Arrow length | Numeric vector >=0 | E(g)$arrowLength <- 15 |
arrowAngle | Arrowhead angle in degrees | Numeric vector in [10, 90] | E(g)$arrowAngle <- 20 |
edgeWeight | Edge weight | Numeric vector >=0 | E(g)$edgeWeight <- 0 |
RedeR provides two wrapper functions to add fixed values to igraph graphs. The att.addv()
function adds a new attribute with a fixed value to all nodes or selected nodes, while att.adde()
function adds a new attribute with a fixed value to all edges. These functions will require that the vertices are named.
## [1] "V1" "V2" "V3" "V4" "V5"
#--- Add 'nodeLabelSize' attribute from a fixed value
g1 <- att.addv(g1, to = "nodeLabelSize", value = 20)
#--- Same as above, but applied only to three nodes
g1 <- att.addv(g1, to = "nodeLabelSize", value = 70,
filter = list("name" = V(g1)$name[1:3]))
#--- Add 'edgeLineType' attribute from a fixed value
g1 <- att.adde(g1, to = "edgeLineType", value = "DOTTED")
## IGRAPH 1c5efd1 UN-- 100 99 -- Barabasi graph
## + attr: name (g/c), power (g/n), m (g/n), zero.appeal (g/n), algorithm
## | (g/c), bgcolor (g/c), name (v/c), nodeLineColor (v/c), nodeSize
## | (v/n), nodeLabelSize (v/n), edgeLineColor (e/c), edgeLineWidth (e/n),
## | edgeLineType (e/c)
Alternatively, RedeR's attributes can be set using the att.mapv()
, att.setv()
, and att.sete()
wrapper functions. The att.mapv()
will map variables from a data frame to igraph vertices, while the att.setv()
and att.sete()
will transform vertex and edge variables into valid attribute types. Next, to demonstrate these functions, we will create a data.frame
object with compatible identifiers.
#--- Create data frame with IDs compatible to 'g1'
df <- data.frame(ID=sample(V(g1)$name))
#--- Add two random variables for demonstration
df$newAttr1 <- rnorm(nrow(df))
df$newAttr2 <- rnorm(nrow(df))
#--- Map 'df' to 'g1' using the att.mapv() function
#Note: 'refcol' indicates a 'df' column for mapping IDs
g1 <- att.mapv(g=g1, dat=df, refcol=1)
#--- Check the new attributes mapped to 'g2'
summary(g1)
## IGRAPH 1c5efd1 UN-- 100 99 -- Barabasi graph
## + attr: name (g/c), power (g/n), m (g/n), zero.appeal (g/n), algorithm
## | (g/c), bgcolor (g/c), name (v/c), nodeLineColor (v/c), nodeSize
## | (v/n), nodeLabelSize (v/n), newAttr1 (v/n), newAttr2 (v/n),
## | edgeLineColor (e/c), edgeLineWidth (e/n), edgeLineType (e/c)
Note that new names were included in the g2
graph, but these names are not valid RedeR's attributes yet. Next, the att.setv()
and att.sete()
functions are used to transform different data types into valid attributes.
# Set 'nodeColor' from 'newAttr1'
g1 <- att.setv(g1, from="newAttr1", to="nodeColor",
breaks=seq(-2,2,0.4), pal=2)
# Set 'nodeSize' from 'newAttr1'
g1 <- att.setv(g1, from="newAttr2", to="nodeSize",
nquant=10, xlim=c(20,50,1))
#--- Check the new attributes set in 'g1'
summary(g1)
## IGRAPH 1c5efd1 UN-- 100 99 -- Barabasi graph
## + attr: name (g/c), power (g/n), m (g/n), zero.appeal (g/n), algorithm
## | (g/c), bgcolor (g/c), legNodeColor (g/x), legNodeSize (g/x), name
## | (v/c), nodeLineColor (v/c), nodeSize (v/n), nodeLabelSize (v/n),
## | newAttr1 (v/n), newAttr2 (v/n), nodeColor (v/c), edgeLineColor (e/c),
## | edgeLineWidth (e/n), edgeLineType (e/c)
This section provides some practical examples of how users might integrate its own pre-processed data into a graph visualization workflow. Please refer to Castro et al. (2016) and Cardoso et al. (2021) for more details about the biological background and experimental design of each example.
Start the RedeR application (i.e. run the startRedeR()
function), and then load the ER.limma
and hs.inter
datasets. The ER.limma
is a data frame with results from a time-course differential expression analysis, listing differentially expressed (DE) genes from estrogen-treated MCF-7 cells for 0, 3, 6, and 12 hours (contrasts: t3-t0, t6-t0, and t12-t0). The hs.inter
is an igraph graph derived from the Human Protein Reference Database (HPRD, release 9). The next snippets list a step-by-step preparation of three nested subgraphs to display in the RedeR application.
Extract a subgraph from the hs.inter
graph and set its attributes using the att.setv()
function. This subgraph will include DE genes called in the t3-t0 contrast. Note that some genes are not listed in the hs.inter
, and that's okay.
#-- Extract a subgraph from the hs.inter graph
deg.t3 <- ER.limma[ER.limma$degenes.t3!=0,]
gt3 <- subg(g=hs.inter, dat=deg.t3, refcol=1)
## ...not all genes found in the network!
#-- Set attributes
gt3 <- att.setv(g=gt3, from="Symbol", to="nodeLabel")
gt3 <- att.setv(g=gt3, from="logFC.t3", to="nodeColor",
breaks=seq(-2,2,0.4), pal=2)
Extract another subgraph from the hs.inter
graph, for DE genes in the t6-t0 contrast:
#--- Extract another subgraph from the hs.inter graph
deg.t6 <- ER.limma[ER.limma$degenes.t6!=0,]
gt6 <- subg(g=hs.inter, dat=deg.t6, refcol=1)
## ...not all genes found in the network!
#--- Set attributes
gt6 <- att.setv(g=gt6, from="Symbol", to="nodeLabel")
gt6 <- att.setv(g=gt6, from="logFC.t6", to="nodeColor",
breaks=seq(-2,2,0.4), pal=2)
Extract another subgraph from the hs.inter
graph, for DE genes in the t12-t0 contrast:
#--- Extract another subgraph from the hs.inter graph
deg.t12 <- ER.limma[ER.limma$degenes.t12!=0,]
gt12 <- subg(g=hs.inter, dat=deg.t12, refcol=1)
## ...not all genes found in the network!
#--- Set attributes
gt12 <- att.setv(g=gt12, from="Symbol", to="nodeLabel")
gt12 <- att.setv(g=gt12, from="logFC.t12", to="nodeColor",
breaks=seq(-2,2,0.4), pal=2)
Now use the addGraphToRedeR()
function to send the three subgraphs to the RedeR application, nesting them into containers. This should start building the nested network depicted in Figure 5. The addGraphToRedeR()
function will return the container IDs, from N1
to N5
, which will be used to identify the graph parents.
#--- Send nested subgraphs to the RedeR application
N1 <- addGraphToRedeR(gt3, gcoord=c(10,25), gscale=20,
isNested=TRUE, theme='th1', zoom=30)
N2 <- addGraphToRedeR(gt6, gcoord=c(20,70), gscale=50,
isNested=TRUE, theme='th1', zoom=30)
N3 <- addGraphToRedeR(gt12, gcoord=c(70,55), gscale=80,
isNested=TRUE, theme='th1', zoom=30)
... and use the nestNodes()
function to nest overlapping genes in the time series:
#--- Nest nodes into the sub-subgraphs
N4 <- nestNodes(nodes=V(gt3)$name, parent=N2, theme='th2')
N5 <- nestNodes(nodes=V(gt3)$name, parent=N3, theme='th2')
nestNodes(nodes=V(gt3)$name, parent=N5, theme='th2')
To simplify the graph, the mergeOutEdges()
function can be used to assign edges to containers:
...then telax the network:
...and add a color legend:
scl <- gt3$legNodeColor$scale
names(scl) <- gt3$legNodeColor$legend
addLegendToRedeR(scl, type="nodecolor",
title="Node color (logFC)", stretch = 0.1)
Next, the selectNodes()
function will zoom-in on the RET gene at different time points:
The TreeAndLeaf package combines tree and force-directed layout algorithms for drawing binary trees, aiming to improve the visualization of dendrogram leaves. RedeR is used to display tree-and-leaf diagrams. Next we will transform an hclust
object into a tree-and-leaf
object, and then display Figure 6 in the RedeR application. Please refer to the TreeAndLeaf package's documentation for additional details and examples.
#-- Convert the 'hclust' object into a 'tree-and-leaf' object
tal <- treeAndLeaf(hc_iris)
#--- Map 'iris' variables to the tree-and-leaf graph
#Note: 'refcol = 0' indicates that 'iris' rownames will be used as mapping IDs
tal <- att.mapv(g = tal, dat = iris, refcol = 0)
#--- Set node attributes using the 'att.setv' wrapper function
cols <- c("#80b1d3","#fb8072","#8dd3c7")
tal <- att.setv(tal, from="Species", to="nodeColor", cols=cols)
tal <- att.setv(tal, from="Species", to="nodeLineColor", cols=cols)
tal <- att.setv(tal, from="Petal.Width", to="nodeSize", nquant=6, xlim=c(5,50,1))
#--- Set other attributes using igraph shortcuts
V(tal)$nodeLabel <- ""
E(tal)$edgeLineColor <- "grey70"
#--- Send the tree-and-leaf graph to RedeR
addGraphToRedeR(tal, zoom=50)
#--- Suggestion: anchor inner nodes to adjust the final layout
selectNodes(V(tal)$name[!V(tal)$isLeaf], anchor=TRUE)
#--- Call 'relax' to fine-tune the leaf nodes
relaxRedeR(p1=10, p2=100, p3=5, p4=120, p5=1, p6=100)
#--- Add legends
addLegendToRedeR(tal, type="nodecolor", title="Species", stretch=0.2)
addLegendToRedeR(tal, type="nodesize", title="PetalWidth")
If you use RedeR, please cite:
Cardoso MA, Rizzardi LEA, Kume LW, Groeneveld C, Trefflich S, Morais DAA, Dalmolin RJS, Ponder BAJ, Meyer KB, Castro MAA. "TreeAndLeaf: an R/Bioconductor package for graphs and trees with focus on the leaves." Bioinformatics, 38(5):1463-1464, 2022. https://bioconductor.org/packages/TreeAndLeaf/
Csardi G and Nepusz T. "The Igraph Software Package for Complex Network Research." InterJournal, ComplexSystems:1695, 2006. https://igraph.org
RedeR 3.2.0 will need the Java Runtime Environment (JRE) version 11 or higher (Java >=11). In order to check the Java on your system, please use the RedPort()
function with checkJava=TRUE
, for example:
RedPort(checkJava=TRUE)
# RedeR will need Java Runtime Environment (Java >=11)
# Checking Java version installed on this system...
# openjdk version "11.0.13" 2021-10-19
# OpenJDK Runtime Environment (build 11.0.13+8-Ubuntu-0ubuntu1.20.04)
# OpenJDK 64-Bit Server VM (build 11.0.13+8-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)
The exact output will vary, but you need to make sure the system meets the minimum version requirement.
## R version 4.4.1 (2024-06-14)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.1 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.20-bioc/R/lib/libRblas.so
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_GB LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: America/New_York
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] TreeAndLeaf_1.18.0 igraph_2.1.1 RedeR_3.2.0 BiocStyle_2.34.0
##
## loaded via a namespace (and not attached):
## [1] jsonlite_1.8.9 compiler_4.4.1 BiocManager_1.30.25
## [4] highr_0.11 crayon_1.5.3 Rcpp_1.0.13
## [7] parallel_4.4.1 jquerylib_0.1.4 scales_1.3.0
## [10] yaml_2.3.10 fastmap_1.2.0 lattice_0.22-6
## [13] R6_2.5.1 knitr_1.48 bookdown_0.41
## [16] munsell_0.5.1 bslib_0.8.0 pillar_1.9.0
## [19] rlang_1.1.4 utf8_1.2.4 cachem_1.1.0
## [22] xfun_0.48 sass_0.4.9 cli_3.6.3
## [25] magrittr_2.0.3 digest_0.6.37 grid_4.4.1
## [28] lifecycle_1.0.4 nlme_3.1-166 vctrs_0.6.5
## [31] evaluate_1.0.1 glue_1.8.0 ape_5.8
## [34] fansi_1.0.6 colorspace_2.1-1 rmarkdown_2.28
## [37] tools_4.4.1 pkgconfig_2.0.3 htmltools_0.5.8.1