--- title: "Basic Usage of **NetworkDistance** Package" author: "Kisung You" output: pdf_document: fig_caption: true vignette: > %\VignetteIndexEntry{Basic Usage of NetworkDistance Package} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## 1. Load Surely, the first thing we are always bound to do is to load the package, ```{r call} library(NetworkDistance) ``` ## 2. Computing Distances Suppose you have $N$ network objects represented as square adjacency matrices. All the functions in the package require your data to be in a form of `list` whose elements are your adjacency matrices. Let's load example data `graph20`. ```{r load} data(graph20) # use `help(graph20)' to see more details. typeof(graph20) # needs to be a list ``` Before proceeding any further, since we have two types of graphs - densely and sparsely connected with $p=0.8$ and $p=0.2$ - we know that the distance matrix should show block-like pattern. Below is two example graphs from the dataset. ```{r showgraph, echo=FALSE, fig.align='center'} suppressMessages(library(igraph)) par(mfrow=c(1,2),pty="s") plot(graph_from_adjacency_matrix(graph20[[7]], mode="undirected"), vertex.size=7, vertex.label=NA, main="graph No.7", edge.arrow.size=.5) plot(graph_from_adjacency_matrix(graph20[[18]], mode="undirected"), vertex.size=7, vertex.label=NA, main="graph No.18", edge.arrow.size=.5) ``` Once you have your data in such a form, all you've got is to run a single-line code to acquire distance numerics, resulting in either a `dist` class object or a square matrix. For example, let's compute *graph diffusion distance* by Hammond et al. (2013) on our example set. ```{r run} dist.gdd <- nd.gdd(graph20) # return as a 'dist' object ``` and you can see the discriminating pattern from the distance matrix `dist.gdd$D` with black represents $0$ and white represents the largest positive number, indicating large deviation from 0. ```{r run_vis1, echo=FALSE, fig.align='center'} par(pty="s") dmat = as.matrix(dist.gdd$D) image(dmat[,20:1],main="pairwise distance matrix",axes=FALSE,col=gray(0:100/100)) ``` Finally, let's compare different methods as well. ```{r compare} dist.wsd <- nd.wsd(graph20) # spectrum-weighted distance dist.dsd <- nd.dsd(graph20, type="SLap") # discrete spectral measure dist.nfd <- nd.nfd(graph20) # network flow distance ``` ```{r run_vis2, echo=FALSE} par(mfrow=c(1,3),pty="s") image(as.matrix(dist.wsd$D)[,20:1],main="nd.wsd",axes=FALSE,col=gray(0:100/100)) image(as.matrix(dist.dsd$D)[,20:1],main="nd.dsd",axes=FALSE,col=gray(0:100/100)) image(as.matrix(dist.nfd$D)[,20:1],main="nd.nfd",axes=FALSE,col=gray(0:100/100)) ``` ## 3. One Application : Embedding Networks, Not Network Embedding Our interest is focused on dealing with a collection of networks, **not** a single network. Therefore, the example we cover here is to **embed** multiple networks, not an embedding of single network and its nodes as points. We will use multidimensional scaling to embed 20 graphs we did before. ```{r embed} gdd2 = stats::cmdscale(dist.gdd$D, k=2) # 2-d embedding from 'gdd' distance wsd2 = stats::cmdscale(dist.wsd$D, k=2) # 'wsd' dsd2 = stats::cmdscale(dist.dsd$D, k=2) # 'dsd' nfd2 = stats::cmdscale(dist.nfd$D, k=2) # 'nfd' ``` ```{r embed_vis, echo=FALSE, fig.align="center"} par(mfrow=c(2,2)) plot(gdd2, main="embedding with 'gdd'", pch=19, xlab="x", ylab="y", cex=0.25) plot(wsd2, main="embedding with 'wsd'", pch=19, xlab="x", ylab="y", cex=0.25) plot(dsd2, main="embedding with 'dsd'", pch=19, xlab="x", ylab="y", cex=0.25) plot(nfd2, main="embedding with 'nfd'", pch=19, xlab="x", ylab="y", cex=0.25) ``` From the figure above, we can see that different measures/metrics reveal a variety of topological or network features. This necessitates the very existence of a package like ours to provide a set of tools for diverse perspectives on the space networks.