【问题标题】:Understand the `Reduce` function了解 `Reduce` 功能
【发布时间】:2015-04-17 05:10:17
【问题描述】:

我对 R 中的 Reduce 函数有疑问。我阅读了它的文档,但我仍然有点困惑。所以,我有 5 个带有基因名称的载体。例如:

v1 <- c("geneA","geneB",""...)
v2 <- c("geneA","geneC",""...)
v3 <- c("geneD","geneE",""...)
v4 <- c("geneA","geneE",""...)
v5 <- c("geneB","geneC",""...)

我想找出至少两个载体中存在哪些基因。有人建议:

Reduce(intersect,list(a,b,c,d,e))

如果有人能向我解释这个语句是如何工作的,我将不胜感激,因为我已经看到 Reduce 在其他场景中使用。

【问题讨论】:

  • 您的问题真的是“我如何才能找到至少两个载体中存在哪些基因/元素?”如果是这样,Reduce()不会有帮助,尽管它可以很容易地回答“哪些基因存在于所有向量中?”的问题

标签: r reduce


【解决方案1】:

假设这个答案末尾给出的输入值,表达式

Reduce(intersect,list(a,b,c,d,e))
## character(0)

给出存在于所有载体中的基因,而不是存在于至少两个载体中的基因。意思是:

intersect(intersect(intersect(intersect(a, b), c), d), e)
## character(0)

如果我们想要至少在两个向量中的基因:

L <- list(a, b, c, d, e)
u <- unlist(lapply(L, unique)) # or:  Reduce(c, lapply(L, unique))

tab <- table(u)
names(tab[tab > 1])
## [1] "geneA" "geneB" "geneC" "geneE"

sort(unique(u[duplicated(u)]))
## [1] "geneA" "geneB" "geneC" "geneE"

注意:我们使用:

a <- c("geneA","geneB")
b <- c("geneA","geneC")
c <- c("geneD","geneE")
d <- c("geneA","geneE")
e <- c("geneB","geneC")

【讨论】:

    【解决方案2】:

    Reduce 接受一个二进制函数和一个数据项列表,并以递归方式将该函数依次应用于列表元素。例如:

    Reduce(intersect,list(a,b,c))
    

    一样
    intersect((intersect(a,b),c)
    

    但是,我认为该构造在这里不会对您有所帮助,因为它只会返回那些 所有 向量共有的元素。

    要计算基因出现的向量数量,您可以执行以下操作:

    vlist <- list(v1,v2,v3,v4,v5)
    addmargins(table(gene=unlist(vlist), vec=rep(paste0("v",1:5),times=sapply(vlist,length))),2,list(Count=function(x) sum(x[x>0])))
           vec
    gene    v1 v2 v3 v4 v5 Count
      geneA  1  1  0  1  0     3
      geneB  1  0  0  0  1     2
      geneC  0  1  0  0  1     2
      geneD  0  0  1  0  0     1
      geneE  0  0  1  1  0     2
    

    【讨论】:

    • 非常感谢您的意见。我以前从未使用过 table 和 addmargins 函数。如果你不介意,我想问问你。
    • 表:所以gene是可以用作因子的对象(即分类数据),vec是维度的名称(即“v1”,“v2”),对吗?我对时间意味着什么感到困惑。它返回长度向量。至于addmargins,它是一个扩展表格以添加边际总数(即感兴趣类别的案例总数)的函数,对吗? “2”意味着添加一列来保存行边际总数,对吗?最后,最后一个参数是一个包含函数的列表。感谢您的时间和帮助!
    • @Johnathan 是的,你是对的。 timesrep 的一个参数,它决定每个元素重复多少次 - 这是为了确保将基因映射到正确的变量。
    • 感谢您的意见。我已阅读 R 的文档。表示 x 中的值(例如 v1...)。我仍然对长度感到困惑。显然,它是一个向量,如果长度为length(x),则给出重复每个元素的次数。例如,如果 v2 的长度为 2,不应该意味着每个元素都重复两次吗?我不明白这如何确保将基因映射到正确的变量。对困惑感到抱歉。我确信这是显而易见的。谢谢!
    • 参数类型的翻转方式很奇怪。如果符合“apply(list, function)”的约定,感觉会好很多。
    【解决方案3】:

    查看Reduce() 正在做什么的一个好方法是使用它的参数accumulate=TRUE 运行它。当accumulate=TRUE 时,它将返回一个向量或列表,其中每个元素在处理x 中列表的前n 个元素后显示其状态。以下是几个例子:

    Reduce(`*`, x=list(5,4,3,2), accumulate=TRUE)
    # [1]   5  20  60 120
    
    i2 <- seq(0,100,by=2)
    i3 <- seq(0,100,by=3)
    i5 <- seq(0,100,by=5)
    Reduce(intersect, x=list(i2,i3,i5), accumulate=TRUE)
    # [[1]]
    #  [1]   0   2   4   6   8  10  12  14  16  18  20  22  24  26  28  30  32  34  36
    # [20]  38  40  42  44  46  48  50  52  54  56  58  60  62  64  66  68  70  72  74
    # [39]  76  78  80  82  84  86  88  90  92  94  96  98 100
    # 
    # [[2]]
    #  [1]  0  6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 96
    # 
    # [[3]]
    # [1]  0 30 60 90
    

    【讨论】:

    • 它可以与大于比较一起使用吗,显然我试过了,我得到了序列中的第一个数字,后跟 11111 或 00000。我对 Reduce('
    • 澄清一下,我知道我可以用 cummin() 得到我想要的结果,只是想在这里理解 Reduce()。
    猜你喜欢
    • 2016-07-12
    • 2020-06-24
    • 1970-01-01
    • 2011-04-21
    • 2021-08-20
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多