% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pairwiseModularity.R
\name{pairwiseModularity}
\alias{pairwiseModularity}
\title{Compute pairwise modularity}
\usage{
pairwiseModularity(graph, clusters, get.weights = FALSE, as.ratio = FALSE)
}
\arguments{
\item{graph}{A \link{graph} object from \pkg{igraph}, usually where each node represents an observation.}

\item{clusters}{Factor specifying the cluster identity for each node.}

\item{get.weights}{Logical scalar indicating whether the observed and expected edge weights should be returned, rather than the modularity.}

\item{as.ratio}{Logical scalar indicating whether the log-ratio of observed to expected weights should be returned.}
}
\value{
By default, an upper triangular numeric matrix of order equal to the number of clusters is returned.
Each entry corresponds to a pair of clusters and is proportional to the difference between the observed and expected edge weights between those clusters.

If \code{as.ratio=TRUE}, an upper triangular numeric matrix is again returned.
Here, each entry is equal to the ratio between the observed and expected edge weights.

If \code{get.weights=TRUE}, a list is returned containing two upper triangular numeric matrices. 
The \code{observed} matrix contains the observed sum of edge weights between and within clusters,
while the \code{expected} matrix contains the expected sum of edge weights under the random model.
}
\description{
Calculate the modularity of each pair of clusters from a graph, based on a null model of random connections between nodes.
}
\details{
This function computes a modularity score in the same manner as that from \code{\link{modularity}}.
The modularity is defined as the (scaled) difference between the observed and expected number of edges between nodes in the same cluster.
The expected number of edges is defined by a null model where edges are randomly distributed among nodes.
The same logic applies for weighted graphs, replacing the number of edges with the summed weight of edges.

Whereas \code{\link{modularity}} returns a modularity score for the entire graph, \code{pairwiseModularity} provides scores for the individual clusters.
The sum of the diagonal elements of the output matrix should be equal to the output of \code{\link{modularity}} 
(after supplying weights to the latter, if necessary).
A well-separated cluster should have mostly intra-cluster edges and a high modularity score on the corresponding diagonal entry,
while two closely related clusters that are weakly separated will have many inter-cluster edges and a high off-diagonal score.

In practice, the modularity may not the most effective metric for evaluating cluster separatedness.
This is because the modularity is proportional to the number of observations, so larger clusters will naturally have a large score regardless of separation.
An alternative approach is to set \code{as.ratio=TRUE}, which returns the ratio of the observed to expected weights for each entry of the matrix.
This adjusts for differences in cluster size and improves resolution of differences between clusters.

Directed graphs are treated as undirected inputs with \code{mode="each"} in \code{\link{as.undirected}}.
In the rare case that self-loops are present, these will also be handled correctly.
}
\examples{
m <- matrix(runif(10000), ncol=10)
clust.out <- clusterRows(m, BLUSPARAM=NNGraphParam(), full=TRUE)
clusters <- clust.out$clusters
g <- clust.out$objects$graph

# Examining the modularity values directly.
out <- pairwiseModularity(g, clusters)
out

# Compute the ratio instead, for visualization
# (log-transform to improve range of colors).
out <- pairwiseModularity(g, clusters, as.ratio=TRUE)
image(log2(out+1))

# This can also be used to construct a graph of clusters,
# for use in further plotting, a.k.a. graph abstraction.
# (Fiddle with the scaling values for a nicer plot.)
g2 <- igraph::graph_from_adjacency_matrix(out, mode="upper",
    diag=FALSE, weighted=TRUE)
plot(g2, edge.width=igraph::E(g2)$weight*10,
    vertex.size=sqrt(table(clusters))*2)

# Alternatively, get the edge weights directly:
out <- pairwiseModularity(g, clusters, get.weights=TRUE)
out

}
\seealso{
\code{\link{makeSNNGraph}}, for one method to construct \code{graph}.

\code{\link{modularity}}, for the calculation of the entire graph modularity.

\code{\link{pairwiseRand}}, which applies a similar breakdown to the Rand index.
}
\author{
Aaron Lun
}
