我有一个看起来像这样的数据集
target.id source.id connected
1 1 0
2 1 0
3 1 0
4 1 0
5 1 0
6 1 0
1 2 1
2 2 0
3 2 1
基本上我有源位置,目的地位置以及它们是否已连接。这里的连接是方向性的,例如,位置1可以连接到位置8而位置8没有连接到位置1(想想航空公司的航班,亚特兰蒂斯可以发送飞往火星的航班,而火星可能不会发送飞往亚特兰蒂斯的航班,这意味着亚特兰蒂斯号与火星相连,而火星则不与亚特兰蒂斯号相连。)
我需要确定完整的'连通地点,所有观测都是彼此的来源和目标。鉴于我有75个位置,我需要成对,3乘3,直到可行。一个示例输出是,对于3乘3,位置3,5和8都是彼此的源和目标。
我试图解决这个问题的方法是将1:length(unique(target.id))
2的所有排列乘以2,3乘3,直到8乘8(8乘8将是我看到的最大集合)然后{ {1}}所有这些。
然而,显然,这太慢了。有更好的方法吗?
答案 0 :(得分:2)
听起来你想要一个有向图中大小为2到8的所有派系,其中节点是你的ids,当源 - >时存在边缘。目标在数据集中标记为已连接。第一步是过滤到连接的边缘,产生类似下面的示例数据:
(filtered <- data.frame(source.id = c(1, 1, 2, 2, 3, 3, 3, 4, 4), target.id = c(2, 3, 1, 3, 1, 2, 4, 3, 5), connected = 1))
# source.id target.id connected
# 1 1 2 1
# 2 1 3 1
# 3 2 1 1
# 4 2 3 1
# 5 3 1 1
# 6 3 2 1
# 7 3 4 1
# 8 4 3 1
# 9 4 5 1
接下来,您可以将数据限制为在两个方向上连接的ID对:
(bidir <- filtered[duplicated(paste(pmin(filtered$source.id, filtered$target.id),
pmax(filtered$source.id, filtered$target.id))),])
# source.id target.id connected
# 3 2 1 1
# 5 3 1 1
# 6 3 2 1
# 8 4 3 1
在这个样本数据中,大小为2的派系是(1,2),(1,3),(2,3)和(3,4),而大小为3的派系是(1,2) ,3)。 igraph包在&#34;接近最佳时间&#34;:
中计算这些library(igraph)
g <- graph.data.frame(bidir, directed=FALSE)
cliques(g, min=2, max=8)
# [[1]]
# + 2/4 vertices, named:
# [1] 2 3
#
# [[2]]
# + 2/4 vertices, named:
# [1] 2 1
#
# [[3]]
# + 2/4 vertices, named:
# [1] 3 4
#
# [[4]]
# + 2/4 vertices, named:
# [1] 3 1
#
# [[5]]
# + 3/4 vertices, named:
# [1] 2 3 1