前段时间我做了类似的 thread 但不幸的是我在那里使用的方法没有给我任何有希望的结果。我想到了如何以不同的方式做到这一点。所以我来了。
当然示例数据:
structure(list(Name1 = c("Mazda RX4", "Mazda RX4", "KIA Ceed",
"Mazda RX4 Wag", "KIA Ceed", "Valiant", "KIA Classic", "Mazda RX4",
"Dacia", "Merc 280", "Duster 360", "Merc 230"), Name2 = c("Mazda RX4 Wag",
"Merc 230", "KIA Sport", "Merc 230", "KIA Classic", "Merc 230",
"KIA Sport", "Merc 240D", "Mazda RX4 Wag", "Merc 450SE", "Valiant",
"Duster 360")), .Names = c("Name1", "Name2"), class = "data.frame", row.names = c(NA,
12L))
此数据框仅包含两列。原始数据有更多,但这次我将只关注那些列。
只是为了表明我想如何将这些人聚集在一起,我将给出一个所需的输出:
structure(list(Name1 = c("Mazda RX4", "Mazda RX4", "KIA Ceed",
"Mazda RX4 Wag", "KIA Ceed", "Valiant", "KIA Classic", "Mazda RX4",
"Dacia", "Merc 280", "Duster 360", "Merc 230"), Name2 = c("Mazda RX4 Wag",
"Merc 230", "KIA Sport", "Merc 230", "KIA Classic", "Merc 230",
"KIA Sport", "Merc 240D", "Mazda RX4 Wag", "Merc 450SE", "Valiant",
"Duster 360"), cluster = c(1, 1, 2, 1, 2, 3, 2, 0, 0, 0, 3, 3
)), .Names = c("Name1", "Name2", "cluster"), row.names = c(NA,
12L), class = "data.frame")
正如您从输出中看到的,我想根据可以在第二列中找到的合作伙伴对汽车进行集群。因此,如果一行中的汽车在下一列中共享相同的“伙伴”,则它们应该聚集在一起。
以及它在表格中的外观,并稍作解释:
Name1 Name2 cluster
1 Mazda RX4 Mazda RX4 Wag 1 ## Two Mazda's same cluster
2 Mazda RX4 Merc 230 1 ## First Mazda with another partner
3 KIA Ceed KIA Sport 2 ## Ceed together with Sport
4 Mazda RX4 Wag Merc 230 1 ## Second Mazda with the same partner
5 KIA Ceed KIA Classic 2 ## Ceed together with Classic
6 Valiant Merc 230 3
7 KIA Classic KIA Sport 2 ## And of course Classic with Sport
8 Mazda RX4 Merc 240D 0 ## First Mazda with another Merc but can't be clustered together in the cluster number 1 because the second Mazda doesn't share this "partner".
9 Dacia Mazda RX4 Wag 0 ## Similar situation but just second Mazda
10 Merc 280 Merc 450SE 0
11 Duster 360 Valiant 3
12 Merc 230 Duster 360 3
这只是我想要实现的简单示例。当然,根据我的原始数据,可能会发生一些对汽车会属于不同集群的情况。簇号可以用逗号分隔,也可以根据需要创建另一列。
对于不能与其他任何东西聚类的对,不必将其设置为 0。他们可以只形成一个单行的集群。反正我不会分析。
我希望我能够准确地解释我想要实现的目标。创造性的想法非常受欢迎。
当然,我想像我在上一个线程中所做的那样,为让我满意的答案开始赏金。
最佳答案
根据评论,“我想创建包含至少 3 个不同基因的簇,并且所有这些基因都相互作用。”
这种描述似乎符合图论中对集团的定义。也就是说,您似乎正在寻找大小为 3 或更大的所有集团。
因此,使用您的示例 data
library(igraph)
g<-graph.data.frame(data,directed=FALSE)
(q<-cliques(g,min=3))
#> [[1]]
#> + 3/12 vertices, named:
#> [1] Mazda RX4 Mazda RX4 Wag Merc 230
#>
#> [[2]]
#> + 3/12 vertices, named:
#> [1] KIA Ceed KIA Classic KIA Sport
#>
#> [[3]]
#> + 3/12 vertices, named:
#> [1] Valiant Duster 360 Merc 230
您认识到任何边缘都可能属于多个派系,因此我为每个派系创建了一个列,并带有一个属于该派系的标志。
ind<-t(apply(data,1,function(r) sapply(q,function(i) all(as.character(r) %in% names(i)))))
(d1<-cbind(data,ind))
Name1 Name2 1 2 3 1 Mazda RX4 Mazda RX4 Wag TRUE FALSE FALSE 2 Mazda RX4 Merc 230 TRUE FALSE FALSE 3 KIA Ceed KIA Sport FALSE TRUE FALSE 4 Mazda RX4 Wag Merc 230 TRUE FALSE FALSE 5 KIA Ceed KIA Classic FALSE TRUE FALSE 6 Valiant Merc 230 FALSE FALSE TRUE 7 KIA Classic KIA Sport FALSE TRUE FALSE 8 Mazda RX4 Merc 240D FALSE FALSE FALSE 9 Dacia Mazda RX4 Wag FALSE FALSE FALSE 10 Merc 280 Merc 450SE FALSE FALSE FALSE 11 Duster 360 Valiant FALSE FALSE TRUE 12 Merc 230 Duster 360 FALSE FALSE TRUE
Or, you could present them in a list in each row of the data.frame.
(d2<-cbind(data,clique=I(as.list(apply(ind,1,which)))))
Name1 Name2 集团
1 马自达 RX4 马自达 RX4 摇摆车 1
2 马自达 RX4 Merc 230 1
3 起亚 Ceed 起亚运动 2
4 马自达 RX4 Wag Merc 230 1
5 起亚 Ceed 起亚经典 2
6 英勇的 Merc 230 3
7 起亚经典起亚运动 2
8 马自达 RX4 Merc 240D
9 达契亚马自达 RX4 摇摆车
10 默 280 默 450SE
11 除尘器 360 英勇 3
12 Merc 230 除尘器 360 3