「R」Robust Rank Aggregation 算法介绍

2020-07-09 15:23:44 浏览数 (1)

介绍

RRA是一种对排名进行整合,获得一个综合性排名列表的算法。

在生物学问题中,经常可能遇到这种情况:

手上有三组实验的结果,但可能:

每组实验测到的基因不同

有的基因在部分实验组里排名很好,但唯独有一组表现很差

三组实验来自不同生物学背景,比如是不同肿瘤的细胞系

那么要怎么根据手上的三组数据来获得一个相对可靠的排名来进一步确定要研究的对象呢?排名整合就可以帮助处理这种问题。

思想

对基因i在样本j里面的原始Rank Rij做标准化,

rij = Rij/Max(Rj)

就是把原始排名变成这个基因在这个样本里相对排在多少位。

此时我们手上就可以获得如下数据。表内所有的r都分布在0-1之间

Gene

Sample1

Sample2

Sample3

A

ra1

ra2

ra3

B

rb1

rb2

rb3

C

rc1

rc2

rc3

……

……

……

……

那么对于基因A,我们就有了它的排名向量:ra={ra1, ra2, ra3}。对其从小到大重新排名。获得ra’={ra1’, ra2’, ra3’} (ra1’<ra2’<ra3’)

如果一个基因在n组样本内都没有出现显著上调/下调,那么它的排名是随机分布在样本内,则假设其标准化分布服从高斯分布。之后就可以根据手上的排名向量进行假设检验,来验证这个假设是否正确。

r(null)是取样自正态分布的一组向量,也按照大小排名获得r(null)’={r(null)1’, r(null)2’, r(null)3’, ……}。

计算:对于基因i标准化后的排名向量里排名第j的rij’,r(null)j’ <= rij’的概率。

如果一个基因一共在n个样本内出现,则其排名向量内有n个排名,所以假设检验后也会获得n个p值。取其中最小的p值来代表这个基因。称之为rho score。

Rho score = min (pij)

Rho score不是精确的p值,原文献在补充资料里提供了计算精准P值的算法,但是补充资料的连接好像已经被移除了……

当总的基因数不是很多(~100)的时候,原文建议可以使用bonferroni校正rho score,得到的padj很接近p值的上界。

示例

比如说,我们手上有一组内地男明星的人气排名(排名纯随机,嗯。名单我随便百度的一个,104人)。可以看到比如马天宇,只有两个表收录了。再比如胡歌,两个榜的排名不错,但还有一个榜的排名就比较靠后。要怎么根据这些排名整合一个相对可以用来参考的综合排名呢?

把这个表格存进R,变量名为stars

「方案1:」

每个榜取Top10,然后做交集。

library(dplyr)

代码语言:javascript复制
    rank1_top10 <- as.character(unlist(filter(stars, Rank1 <= 10)[1]))
    rank2_top10 <- as.character(unlist(filter(stars, Rank2 <= 10)[1]))
    rank3_top10 <- as.character(unlist(filter(stars, Rank3 <= 10)[1]))

不难看出,这样做,如果同时对三个榜Top10取交集,那么就只能剩下王俊凯了……

不过划cutoff再取Overlap的话,确实可以获得一些很solid的candidate。但有时候如果最后剩下的candidate太少,也并不是我们想要的结果。

「方案2:rra」

先构建一个list,把排名后的名单存进去。

代码语言:javascript复制
    
  #使用dplyr的arrange对列表排名。因为我把数据整合在了一张总表里,所以排名时先挑出对应榜单,然后去掉na,再根据Rank排名,之后只取排名后的明星名字。以character形式保存。
    as.character(unlist(arrange(na.omit(stars[,c(1,2)]),Rank1)[1]))
  • 先看一眼根据Rank1排名后的结果
  • 这个就是我们需要存入list的格式
代码语言:javascript复制
    star_glist <- list(as.character(unlist(arrange(na.omit(stars[,c(1,2)]),Rank1)[1])),as.character(unlist(arrange(na.omit(stars[,c(1,3)]),Rank2)[1])),as.character(unlist(arrange(na.omit(stars[,c(1,4)]),Rank3)[1])))

  • 可以看到,三个榜分别收录了104,38,92人。
代码语言:javascript复制
    library(RobustRankAggreg)
#进行rra
    star_rra <- aggregateRanks(star_glist)
#补上rra之后的排名
    star_rra <- cbind(star_rra, "rra_rank" = seq(1,nrow(star_rra)))
#可以看到rra针对各个榜单的排名重新给每个明星计算了分数。按照分数就可以获得新的整合后的排名

  • 再补上原排名,看原排名和现排名的差别
代码语言:javascript复制
    star_rra <- left_join(star_rra, stars, by = "Name")

比如王俊凯,三榜第一,那么自然最后排名也是第一。第二名的邓伦排名是12/104,3/38,5/92,都还不错,整合之后排在第二。然后也有吴建豪这种14/104,30/38,2/92,在第二个榜单中排名已经倒数,但由于另外两个榜单表现都尚佳,最后排在了第10。

0 人点赞