2 votes

trouver le sous-ensemble le plus fréquent dans la base de données

J'ai donc la base de données suivante :

et ce que je veux, c'est trouver la combinaison de gènes qui sont le plus souvent présents ensemble.

  sample genea geneb genec gened genee genef
1      1     1     1     1     0     0     0
2      2     1     1     1     0     0     0
3      3     1     0     0     1     1     1
4      4     0     0     0     0     0     0
5      5     1     0     1     1     1     1
6      6     0     0     0     0     0     0

Donc, dans ce cas, mon résultat souhaité serait : gène a + c = 3 échantillons se chevauchent.

test[sort.list(colSums(test[,-1]), decreasing=TRUE)[1:15] +1]) me donne une liste contenant au maximum 1 valeur par gène. Mais je suis bloqué avec ceci.

Comment aborder cette question ?

2voto

Maël Points 644

Il se peut qu'elle ne convienne pas à tous les cas, mais voici un début :

comb <- combn(colnames(df[-1]), m = 2)
overlap <- sapply(1:ncol(comb), \(i) sum(rowSums(df[comb[, i]]) == 2))

list(max.overlap = max(overlap),
     wm = df[comb[, which.max(overlap)]])

# $max.overlap
# [1] 3
# 
# $wm
#   genea genec
# 1     1     1
# 2     1     1
# 3     1     0
# 4     0     0
# 5     1     1
# 6     0     0

2voto

Jay Points 1879

Une solution consisterait à utiliser crossprod() :

library(tidyr)
library(dplyr)

dat %>%
  pivot_longer(-sample) %>%
  filter(value == 1) %>%
  select(-value) %>%
  table() %>%
  crossprod() %>%
  replace(lower.tri(., diag = TRUE), NA) %>%
  as.data.frame.table() %>%
  slice_max(Freq)

   name name.1 Freq
1 genea  genec    3

1voto

Basti Points 981

Si vous souhaitez visualiser les intersections, vous pouvez utiliser ComplexUpset paquet :

library(ComplexUpset)
ComplexUpset::upset(test[,-1],colnames(test[,-1]))

Mais elle risque de ne pas être utile si vous l'appliquez à un grand nombre de gènes.

enter image description here

1voto

Données :

test <- data.frame(sample = 1:6, 
                   genea = c(1L, 1L, 1L, 0L, 1L, 0L), 
                   geneb = c(1L, 1L, 0L, 0L, 0L, 0L), 
                   genec = c(1L, 1L, 0L, 0L, 1L, 0L), 
                   gened = c(0L, 0L, 1L, 0L, 1L, 0L), 
                   genee = c(0L, 0L, 1L, 0L, 1L, 0L), 
                   genef = c(0L, 0L, 1L, 0L, 1L, 0L))

Compter les matchs :

data.frame(
  count = colSums(combn(subset(test,, -sample), 2, rowSums) == 2),
  gene = t(combn(subset(test,, -sample), 2, colnames ))) 

#>    count gene.1 gene.2
#> 1      2  genea  geneb
#> 2      3  genea  genec
#> 3      2  genea  gened
#> 4      2  genea  genee
#> 5      2  genea  genef
#> 6      2  geneb  genec
#> 7      0  geneb  gened
#> 8      0  geneb  genee
#> 9      0  geneb  genef
#> 10     1  genec  gened
#> 11     1  genec  genee
#> 12     1  genec  genef
#> 13     2  gened  genee
#> 14     2  gened  genef
#> 15     2  genee  genef

Filtrer ceux qui ont le plus grand nombre de correspondances

subset(
  data.frame(
    count = colSums(combn(subset(test,, -sample), 2, rowSums) == 2),
    gene = t(combn(subset(test,, -sample), 2, colnames ))), 
  count == max(count))

#>   count gene.1 gene.2
#> 2     3  genea  genec

Créé le 2022-11-09 avec reprex v2.0.2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X