了解 `Reduce` 函数
Understand the `Reduce` function
我对 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
采用二元函数和数据项列表,并以递归方式将该函数连续应用于列表元素。例如:
Reduce(intersect,list(a,b,c))
与
相同
intersect((intersect(a,b),c)
但是,我认为该构造不会对您有所帮助,因为它只会 return 那些 所有 向量共有的元素。
要计算一个基因出现的载体数量,您可以执行以下操作:
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
查看 Reduce()
正在做的事情的一个好方法是 运行 它及其参数 accumulate=TRUE
。当 accumulate=TRUE
时,它将 return 一个向量或列表,其中每个元素在处理 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
假设在此答案末尾给出的输入值,表达式
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")
我对 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
采用二元函数和数据项列表,并以递归方式将该函数连续应用于列表元素。例如:
Reduce(intersect,list(a,b,c))
与
相同intersect((intersect(a,b),c)
但是,我认为该构造不会对您有所帮助,因为它只会 return 那些 所有 向量共有的元素。
要计算一个基因出现的载体数量,您可以执行以下操作:
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
查看 Reduce()
正在做的事情的一个好方法是 运行 它及其参数 accumulate=TRUE
。当 accumulate=TRUE
时,它将 return 一个向量或列表,其中每个元素在处理 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
假设在此答案末尾给出的输入值,表达式
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")