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 @ref(fig:fig1).
The RedeR/R package sets all details to initialize the R-to-Java
interface. Next, the startRedeR()
function will launch the
RedeR application (Figure @ref(fig:fig1)),
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 @ref(fig:fig2)):
## 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 8d219d6 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
@ref(fig:fig3)). 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 4f55582 U--- 0 0 --
## + edges from 4f55582:
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 699105a 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 @ref(fig:fig4)A. 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 699105a 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 @ref(tab:tab1), @ref(tab:tab2), and @ref(tab:tab3) list all command-line attributes available for the current version (RedeR 3.3.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 699105a 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 699105a 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 699105a 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 @ref(fig:fig5). 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
@ref(fig:fig6) 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.3.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: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 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: Etc/UTC
## 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.3.0 BiocStyle_2.35.0
##
## loaded via a namespace (and not attached):
## [1] nlme_3.1-166 cli_3.6.3 knitr_1.48
## [4] rlang_1.1.4 xfun_0.48 highr_0.11
## [7] jsonlite_1.8.9 glue_1.8.0 colorspace_2.1-1
## [10] buildtools_1.0.0 htmltools_0.5.8.1 maketools_1.3.1
## [13] sys_3.4.3 sass_0.4.9 scales_1.3.0
## [16] rmarkdown_2.28 grid_4.4.1 munsell_0.5.1
## [19] evaluate_1.0.1 jquerylib_0.1.4 fastmap_1.2.0
## [22] ape_5.8 yaml_2.3.10 lifecycle_1.0.4
## [25] BiocManager_1.30.25 compiler_4.4.1 Rcpp_1.0.13
## [28] pkgconfig_2.0.3 lattice_0.22-6 digest_0.6.37
## [31] R6_2.5.1 parallel_4.4.1 magrittr_2.0.3
## [34] bslib_0.8.0 tools_4.4.1 cachem_1.1.0