J'ai une question sur la fonction Réduire dans R. J'ai lu sa documentation, mais je suis encore un peu confus. Donc, j'ai 5 vecteurs avec le nom des gènes. Par exemple:
v1 <- c("geneA","geneB",""...)
v2 <- c("geneA","geneC",""...)
v3 <- c("geneD","geneE",""...)
v4 <- c("geneA","geneE",""...)
v5 <- c("geneB","geneC",""...)
Et je voudrais savoir quels gènes sont présents dans au moins deux vecteurs. Certaines personnes ont suggéré:
Reduce(intersect,list(a,b,c,d,e))
J'apprécierais grandement si quelqu'un pouvait s'il vous plaît m'expliquer comment fonctionne cette déclaration, car j'ai vu réduire utilisé dans d'autres scénarios.
Reduce
prend une fonction binaire et une liste d'éléments de données et applique successivement la fonction aux éléments de la liste de manière récursive. Par exemple:
Reduce(intersect,list(a,b,c))
est le même que
intersect((intersect(a,b),c)
Cependant, je ne pense pas que cette construction vous aidera ici car elle ne renverra que les éléments communs aux vecteurs tous.
Pour compter le nombre de vecteurs dans lesquels un gène apparaît, vous pouvez procéder comme suit:
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
Une belle façon de voir ce que fait Reduce()
est de l'exécuter avec son argument accumulate=TRUE
. Quand accumulate=TRUE
, il retournera un vecteur ou une liste dans laquelle chaque élément montre son état après avoir traité les premiers n éléments de la liste dans x
. Voici quelques exemples:
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
En supposant les valeurs d'entrée données à la fin de cette réponse, l'expression
Reduce(intersect,list(a,b,c,d,e))
## character(0)
donne les gènes qui sont présents dans tous les vecteurs, pas les gènes qui sont présents dans au moins deux vecteurs. Ça veut dire:
intersect(intersect(intersect(intersect(a, b), c), d), e)
## character(0)
Si nous voulons les gènes qui sont dans au moins deux vecteurs:
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"
ou
sort(unique(u[duplicated(u)]))
## [1] "geneA" "geneB" "geneC" "geneE"
Remarque: Nous avons utilisé:
a <- c("geneA","geneB")
b <- c("geneA","geneC")
c <- c("geneD","geneE")
d <- c("geneA","geneE")
e <- c("geneB","geneC")