有效地计算R中的一组共识成员

时间:2018-04-07 19:34:44

标签: r set permutation combn

我有一个非常大(数百万点)的连通图和许多潜在的分割算法来确定群组成员资格。是否存在集合中的现有实现或类似的R包,用于计算可能的集合中的共识集。

一个例子:

我们说我有10个总分和3个选择组和成员的算法。

> algorithm1<-list(c(1,2,3),c(4,5,6),c(7,8,9,10))
> algorithm2<-list(c(1,2,3),c(4,6),c(5,7,8,9,10))
> algorithm3<-list(c(1,2,3),c(4,6),c(5,7,8),c(9,10))
> algorithm1
[[1]]
[1] 1 2 3

[[2]]
[1] 4 5 6

[[3]]
[1]  7  8  9 10

> algorithm2
[[1]]
[1] 1 2 3

[[2]]
[1] 4 6

[[3]]
[1]  5  7  8  9 10

> algorithm3
[[1]]
[1] 1 2 3

[[2]]
[1] 4 6

[[3]]
[1] 5 7 8

[[4]]
[1]  9 10

所有三种算法都认为1,2,3中存在成员资格,但其余组需要多数规则算法来确定与输入组相比最小化损失的最小组数。这感觉就像一个可能解决的排列/组合区域。这不是我的领域,我需要朝着正确的方向努力。

我考虑过的一个不完整的事情是在成员之间生成成对链接,其链接强度等于一对点包含在集合中的次数。

> library(reshape2)
> 
> pairwise_count<-function(x){
+   
+ #For each group, get all pairwise combination of members
+   m<-lapply(x,function(y){
+     as.data.frame(t(combn(y,2)))
+   })
+   
+ #Bind groups into a dataframe and give it a count column
+   df<-bind_rows(m)
+   colnames(df)<-c("Point1","Point2")
+   return(df)
+ }
> 
> #Example
> pairwise_count(algorithm1)
   Point1 Point2
1       1      2
2       1      3
3       2      3
4       4      5
5       4      6
6       5      6
7       7      8
8       7      9
9       7     10
10      8      9
11      8     10
12      9     10
> #Compute for all algorithms
> alldf<-list(algorithm1=pairwise_count(algorithm1),algorithm2=pairwise_count(algorithm2),algorithm3=pairwise_count(algorithm3))
> alldf<-melt(alldf,id.vars=c("Point1","Point2"))
> 
> #Get consensus probability that a pair are in the same set.
> library(dplyr)
> alldf %>% group_by(Point1,Point2) %>% summarize(n=n()/3)
# A tibble: 16 x 3
# Groups:   Point1 [?]
   Point1 Point2     n
    <dbl>  <dbl> <dbl>
 1     1.     2. 1.00 
 2     1.     3. 1.00 
 3     2.     3. 1.00 
 4     4.     5. 0.333
 5     4.     6. 1.00 
 6     5.     6. 0.333
 7     5.     7. 0.667
 8     5.     8. 0.667
 9     5.     9. 0.333
10     5.    10. 0.333
11     7.     8. 1.00 
12     7.     9. 0.667
13     7.    10. 0.667
14     8.     9. 0.667
15     8.    10. 0.667
16     9.    10. 1.00 
> 
> # How to choose final sets?

编辑#1以下代码重现上述功能。

library(reshape2)
library(dplyr)

algorithm1<-list(c(1,2,3),c(4,5,6),c(7,8,9,10))
algorithm2<-list(c(1,2,3),c(4,6),c(5,7,8,9,10))
algorithm3<-list(c(1,2,3),c(4,6),c(5,7,8),c(9,10))

pairwise_count<-function(x){

 #For each group, get all pairwise combination of members
   m<-lapply(x,function(y){
     as.data.frame(t(combn(y,2)))
   })

 #Bind groups into a dataframe and give it a count column
   df<-bind_rows(m)
   colnames(df)<-c("Point1","Point2")
   return(df)
 }

#Example
pairwise_count(algorithm1)

#Compute for all algorithms
alldf<-list(algorithm1=pairwise_count(algorithm1),algorithm2=pairwise_count(algorithm2),algorithm3=pairwise_count(algorithm3))
alldf<-melt(alldf,id.vars=c("Point1","Point2"))

#Get consensus probability that a pair are in the same set.
alldf %>% group_by(Point1,Point2) %>% summarize(n=n()/3)

# How to choose final sets?

1 个答案:

答案 0 :(得分:0)

所以这里可能会让你更接近你的目标.. diceR包实现了“共识聚类”。以下是它对您的样本的工作方式。这表示“对我的三组群集进行共识聚类,不重新采样数据子集,否则会显示大量NAreps以确定迭代次数,然后你还可以选择一个或多个聚类算法(例如hcpamdianakm)和一个或多个距离指标(distance=c("euclidean","minkowski"))。

以下是您的数据的一个非常简短的示例,在最终解决方案中要求“三个或四个群集”,并且只使用具有欧氏距离的层次聚类(默认值):

> library(diceR)
> df <- cbind(unlist(algorithm1),unlist(algorithm2),unlist(algorithm3))
> consensus_cluster(df, nk=3:4, p.item=1, reps=10, algorithms=c("hc"))
, , HC_Euclidean, 3

   R1 R2 R3 R4 R5 R6 R7 R8 R9 R10
1   1  1  2  2  3  3  2  1  3   1
2   1  1  2  2  3  3  2  1  3   1
3   1  1  2  2  3  3  2  1  3   1
4   1  1  2  2  3  3  2  1  3   1
5   2  2  3  1  2  1  3  3  1   2
6   2  2  3  1  2  1  3  3  1   2
7   3  3  1  3  1  2  1  2  2   3
8   3  3  1  3  1  2  1  2  2   3
9   3  3  1  3  1  2  1  2  2   3
10  3  3  1  3  1  2  1  2  2   3

, , HC_Euclidean, 4

   R1 R2 R3 R4 R5 R6 R7 R8 R9 R10
1   1  4  2  2  3  4  3  1  4   1
2   1  1  2  2  3  4  3  1  4   1
3   1  1  4  2  3  3  2  1  3   1
4   1  1  4  2  3  3  2  1  3   1
5   2  2  3  1  2  1  4  3  1   2
6   2  2  3  1  2  1  4  3  1   2
7   3  3  1  4  1  2  1  2  2   3
8   3  3  1  4  1  2  1  2  2   3
9   4  3  1  3  1  2  1  2  2   4
10  4  3  1  3  4  2  1  4  2   4

最后一列显示最终迭代的集群分配。你将不得不使用聚类方法,距离度量和代表数来找到适合你的方法,但这里有一个小插图可以帮助你做到这一点:https://cran.r-project.org/web/packages/diceR/vignettes/overview.html < / p>

这里还有一篇学术论文:https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5769335/

希望这有点帮助:)