您可以通过构建表示矩阵的格图来解决此问题,其中仅当顶点具有相同类型时才保留边:
# Build initial matrix and lattice graph
library(igraph)
mat <- matrix(c(1, 1, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1, 3, 1, 3, 1, 1, 1, 3, 1), nrow=4)
labels <- as.vector(mat)
g <- graph.lattice(dim(mat))
lyt <- layout.auto(g)
# Remove edges between elements of different types
edgelist <- get.edgelist(g)
retain <- labels[edgelist[,1]] == labels[edgelist[,2]]
g <- delete.edges(g, E(g)[!retain])
# Take a look at what we have
plot(g, layout=lyt)
顶点按列编号。很容易看出,我们需要做的就是抓取该图的组件:
matrix(clusters(g)$membership, nrow=nrow(mat))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 2 2 3 4
# [2,] 1 1 2 4 4
# [3,] 1 2 2 5 5
# [4,] 1 1 1 1 1
如果您想在晶格中包含对角线,您可以从邻域大小为 2 的晶格开始,然后限制元素之间的距离不超过一行或一列。考虑以下矩阵:
[A B C B]
[B A A A]
由于包含对角链接,以下代码将捕获 4 个组,而不是 6 个:
# Build initial matrix and lattice graph (neighborhood size 2)
mat <- matrix(c(1, 2, 2, 1, 3, 1, 2, 1), nrow=2)
labels <- as.vector(mat)
rows <- (seq(length(labels)) - 1) %% nrow(mat)
cols <- ceiling(seq(length(labels)) / nrow(mat))
g <- graph.lattice(dim(mat), nei=2)
# Remove edges between elements of different types or that aren't diagonal
edgelist <- get.edgelist(g)
retain <- labels[edgelist[,1]] == labels[edgelist[,2]] &
abs(rows[edgelist[,1]] - rows[edgelist[,2]]) <= 1 &
abs(cols[edgelist[,1]] - cols[edgelist[,2]]) <= 1
g <- delete.edges(g, E(g)[!retain])
# Cluster to obtain final groups
matrix(clusters(g)$membership, nrow=nrow(mat))
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 2 1 1 1