首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定一个路径列表及其基因是否都包含在另一个列表中

确定一个路径列表及其基因是否都包含在另一个列表中
EN

Code Review用户
提问于 2018-04-18 22:06:17
回答 1查看 66关注 0票数 3

我正在评估是否有一系列的路径及其基因包含在另一条路径中。所以我的想法是创建一个只做一个比较的函数。

代码语言:javascript
复制
all_in <- function(x, y) {
  if (length(x) > length(y)) {
    0
  } else {
    ifelse(all(x %in% y), 1, 0)
  }
}

然后Vectorize可以使用外部

代码语言:javascript
复制
all_in_vec <- Vectorize(all_in, vectorize.args = c("x", "y"))

并以下列方式使用:

代码语言:javascript
复制
nested <- outer(paths2genes, paths2genes, all_in_vec)

示例:

代码语言:javascript
复制
paths2genes <- structure(list(`1430728` = c("10", "9"), `156580` = c("10", "3", 
"9"), `156582` = c("10", "9"), `194840` = c("2", "3"), `211859` = c("10", 
"9")), .Names = c("1430728", "156580", "156582", "194840", "211859"
))

测试:

代码语言:javascript
复制
library(testthat)
expect_true(all(diag(nested) == 1L))
expect_equal(nested[1, 2], 1L)

然而,我最近发现,应该避免Vectorize,以支持内置的向量化。我遗漏了什么内置的方法吗?如何将此代码向量化?

EN

回答 1

Code Review用户

回答已采纳

发布于 2018-04-19 03:49:54

如果您要在您的cat("hello")函数的顶部添加一个all_in,您会发现您的函数被调用了25次,每次组合(对)路径都调用一次。因此,是的,尽管使用过Vectorized,但它本质上仍然是一个很大的旧循环。下面是编写向量化函数的方法,这样就只调用了一次或两次繁重的函数(%in%,或者在我的例子中是match):

代码语言:javascript
复制
all_in_outer <- function(list_x, list_y) {
  uniq_x <- unique(unlist(list_x, use.names = FALSE))
  len_x <- vapply(list_x, length, integer(1L))
  as_mat <- function(list_a, ids = uniq_x) {
    vec <- unlist(list_a, use.names = FALSE)
    len <- vapply(list_a, length, integer(1L))
    idx <- rep(seq_along(list_a), len)
    mat <- matrix(0L, nrow = length(list_a), ncol = length(ids),
                  dimnames = list(names(list_a), ids))
    mat[cbind(idx, match(vec, ids))] <- 1L
    mat
  }
  (as_mat(list_x) %*% t(as_mat(list_y)) == len_x) * 1
}

all_in_outer(paths2genes, paths2genes)
#         1430728 156580 156582 194840 211859
# 1430728       1      1      1      0      1
# 156580        0      1      0      0      0
# 156582        1      1      1      0      1
# 194840        0      0      0      1      0
# 211859        1      1      1      0      1

一些解释:当我们在第一个论点(10932)中找到跨越所有通路的独特基因列表后,我们将这两个参数转化为一个矩阵A,如果路径i包含基因j,则为A[i,j] = 1,否则为0。对于paths2genes,这个矩阵是as_mat(paths2genes)

代码语言:javascript
复制
#         10 9 3 2
# 1430728  1 1 0 0
# 156580   1 1 1 0
# 156582   1 1 0 0
# 194840   0 0 1 1
# 211859   1 1 0 0

然后,利用两个这样的矩阵之间的矩阵乘法,得到每个可能的组合路径的基因匹配数。然后,您只需将匹配的数量与路径的长度:(as_mat(list_x) %*% t(as_mat(list_y)) == len_x)进行比较即可。

在将每个输入转换为0和1的矩阵时,请参阅以下特定代码行:mat[cbind(idx, match(vec, ids))] <- 1L。这就是矩阵中填充的部分。通过对match的一次调用,它是完全矢量化的。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/192410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档