Подтвердить что ты не робот

Понимать функцию "Уменьшить"

У меня вопрос о функции уменьшения в R. Я читаю его документацию, но я все еще немного смущен. Итак, у меня есть 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))

Я был бы очень признателен, если бы кто-нибудь мог объяснить мне, как это выражение работает, потому что я видел сокращение, используемое в других сценариях. Спасибо!

4b9b3361

Ответ 1

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

Ответ 2

Хороший способ видеть, что делает Reduce(), - запустить его со своим аргументом accumulate=TRUE. Когда accumulate=TRUE, он вернет вектор или список, в котором каждый элемент показывает свое состояние после обработки первых n элементов списка в x. Вот несколько примеров:

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

Ответ 3

Предполагая входные значения, указанные в конце этого ответа, выражение

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")