0

我有list一个integer vector

set.seed(1)
l <- list(g1=as.integer(runif(10,1,100)),
          g2=as.integer(runif(5,1,100)),
          g3=as.integer(runif(5,1,100)),
          g4=as.integer(runif(8,1,100)))

(实际上它有 1000 个元素长,向量元素的平均长度为 100 个)

我想计算所有' 元素对与其对应的/之间的intersectionover 。unionlhypergeometricfisher.test p-value

这是我目前正在做的事情:

  1. 首先,我生成一个矩阵来存储l其所有元素对的索引:

    idx.mat <- t(combn(1:length(l),2))
    

这部分非常快,可以使用combnPrim更快

  1. 然后我运行这个函数来获得我想要的输出:

    res.df <- do.call(rbind, lapply(1:nrow(idx.mat), function(i){ gi.length <- length(l[[idx.mat[i,1]]]) gj.length <- length(l[[idx.mat[i,2]]]) set.diff.1 <- length(setdiff(l[[idx.mat[i,1]]],l[[idx.mat[i,2]]])) set.diff.2 <- length(setdiff(l[[idx.mat[i,2]]],l[[idx.mat[i,1]]])) gi.gj.inter <- length(intersect(l[[idx.mat[i,1]]],l[[idx.mat[i,2]]])) gi.gj.union <- length(unique(c(l[[idx.mat[i,1]]],l[[idx.mat[i,2]]]))) p.value <- fisher.test(matrix(c(gi.length+gj.length- gi.gj.union,set.diff.1,set.diff.2,gi.gj.inter),nrow=2),alternative="greater")$p.value return(data.frame(gi=names(l)[idx.mat[i,1]], gj=names(l)[idx.mat[i,2]], gi.gj.inter=gi.gj.inter, gi.gj.union=gi.gj.union, gi.gj.iou=gi.gj.inter/gi.gj.union, gi.gj.iou.p.val=p.value, stringsAsFactors=F)) }))

但是对于我的实际数据大小,这有点慢。

知道如何更快地实现这一目标吗?

4

1 回答 1

1

尝试表示l为 1/0 矩阵:

max.val = max(sapply(l, max))
mat = do.call(rbind, lapply(l, function(x) {z = rep(0, max.val); z[x] = 1; z}))

现在您可以轻松地预先计算成对的交集和并集:

pair_intsct = mat %*% t(mat)

pair_union = outer(rowSums(mat), rowSums(mat), '+') - pair_intsct
于 2017-01-18T07:13:54.127 回答