[DEBUTANTE} fonction et lapply sur liste de matrices

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Chrystelle Delord
Messages : 33
Enregistré le : 09 Avr 2013, 12:50

[DEBUTANTE} fonction et lapply sur liste de matrices

Messagepar Chrystelle Delord » 30 Mai 2017, 06:19

Bonjour à tous !


Veuillez m'excuser par avance pour la question bien naïve à venir, je ne parviens cependant pas à trouver de réponse sur les forums ou les cours en ligne.

Je souhaite travailler sur un objet R de type list() qui consiste en un ensemble de tableaux comme le montre l'exemple ci-dessous :

Code : Tout sélectionner

$HGY10955
   [,1] [,2] [,3] [,4]  [,5]  [,6]  [,7] [,8]       [,9]      [,10] [,11] [,12]
01    1 0.98    1    1 0.975 0.975 0.975    1 0.98333333 0.97368421     1  0.95
02    0 0.02    0    0 0.025 0.025 0.025    0 0.01666667 0.02631579     0  0.05

$HGY11092
   [,1] [,2]      [,3]  [,4] [,5]       [,6]  [,7] [,8] [,9] [,10] [,11] [,12]
01 0.05    0 0.1052632 0.125  0.1 0.08333333 0.025 0.05    0     0     0     0
02 0.95    1 0.8947368 0.875  0.9 0.91666667 0.975 0.95    1     1     1     1

$HGY11282
   [,1]       [,2]       [,3] [,4] [,5] [,6] [,7] [,8] [,9]     [,10]      [,11] [,12]
01    1 0.97727273 0.94736842    1  0.9    1    1    1    1 0.8947368 0.95652174 0.975
02    0 0.02272727 0.05263158    0  0.1    0    0    0    0 0.1052632 0.04347826 0.025


Pour info au cas où, il s'agit de fréquences alléliques pour plusieurs loci (chacun constituant un des tableaux) et pour plusieurs stations (colonnes des tableaux). Ces données ont été obtenues via la fonction readGenepop du package diveRsity de K. Keenan.

J'ai renommé chaque tableau de ma liste à l'aide des noms de mes différents loci. A présent,je voudrais effectuer la chose suivante :
Pour chaque tableau (donc chaque locus), je veux savoir si ce locus est bien polymorphe à 0.95 dans au moins une des 12 stations. Ceci revient donc à détecter les locis fixés, donc présent une fréquence allélique <=0.05 dans chaque station.

Pour l'instant, je cherche pour chaque locus à tester les fréquences des allèles : si, dans une des deux lignes du tableau, la valeur maximale de la ligne est inférieure à 0.05, alors l'allèle est trop rare pour que le locus soit considéré comme polymorphe. Je veux donc pouvoir récupérer le nom du tableau en question (le nom du locus) et le stocker dans une variable. J'ai voulu écrire une mini-fonction pour tester les lignes de mes tableaux, puis utiliser lapply pour appliquer cette fonction à chaque tableau de ma liste complète :

Code : Tout sélectionner

basic <- assign(paste("Info_", Code, sep = ""), readGenepop(infile="donnees.gen", gp=2)) # obtention des fréquences alléliques
names(basic$allele_freq) <- basic$loci_names # je renomme chaque tableau de la liste [i]basic$allele_freq[/i] avec les noms des loci

mono <- list() # Initialisation de ma liste de marqueurs monomorphes
n <- 0 # Initialisation d'un indice pour récupérer l'élément de la liste basic$allele_freq correspondant à un locus monomorphe

monomorphic <- function(e)
{
  n <- n+1 # Incrémentation de l'indice
  for(i in 1:nrow(e)) {
    if(max(e[i,])<0.05) {
      mono[[length(mono)+1]] <- names(basic$allele_freq[n]) # Ajout du nom du locus monomorphe dans ma variable [i]mono[/i].
    }
  }
}

lapply(basic$allele_freq, monomorphic)


Je sais que quelque chose cloche au niveau de la logique de ma fonction. "e" est sensé représenter un élément de la liste (donc un tableau) mais du coup je suppose que bien entendu R est perdu, puisque la fonction s'applique au tableau directement et non à ma liste... mais du coup je ne vois pas comment faire. Il y avait peut-être une manière plus simple de procéder pour récupérer (et éliminer) mes loci monomorphes, mais je n'ai toutefois pas vraiment trouvé de commande toute prête pour cela. De plus, ça me permet de m'entraîner :)


Je suis donc preneuse de tout conseil concernant l'écriture de fonctions, surtout pour ensuite les appliquer avec un lapply :) Vous remerciant par avance et vous souhaitant très bonne journée,


Chrystelle

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: [DEBUTANTE} fonction et lapply sur liste de matrices

Messagepar Gabriel Terraz » 30 Mai 2017, 08:02

Salut,
Je n'ai pas compris exactement ce que tu voulais au final. Je te propose ceci qui permet de récupérer les noms de locus dont toutes les valeurs sont inférieures à 0.05.

Données bidons :

Code : Tout sélectionner

malist <- replicate(3, matrix(rnorm(10), 2), simplify = F)
names(malist) <- paste("locus", 1:3, sep="")
malist
$locus1
           [,1]      [,2]       [,3]        [,4]       [,5]
[1,]  0.3918677 -1.485195 -0.9721378 -0.10447954 -0.4976907
[2,] -0.5589333  1.904475  0.1165181  0.02489622 -0.7901430

$locus2
          [,1]      [,2]      [,3]       [,4]       [,5]
[1,] -1.895630  1.722981 1.1575756 -0.8858171 -0.5858328
[2,]  1.463495 -1.358643 0.4403608  0.5719744 -0.6215808

$locus3
           [,1]      [,2]       [,3]       [,4]       [,5]
[1,] -1.5616464 0.3359264 -0.8165343  0.7433729 -0.6793545
[2,] -0.3441388 2.3186360 -0.7755646 -0.4816707  0.5086903


Code : Tout sélectionner

names(malist)[lapply(malist, max) < 2]
[1] "locus1" "locus2"


Attention j'ai mis inférieure à deux, il faut mettre 0.05 !

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: [DEBUTANTE} fonction et lapply sur liste de matrices

Messagepar Mickael Canouil » 30 Mai 2017, 08:02

Bonjour,

Une solution consisterait à tester directement la condition sur la matrice/tableau, puis de vérifier si la condition est vraie au moins une fois, cela permet de générer un vecteur logique de même taille que le nombre de loci.

Code : Tout sélectionner

isPolymorph <- sapply(basic$allele_freq, function (itab) {
   any(itab>0.95) # any(itab<0.05)
})

Il suffit ensuite de récupérer les noms des locis en utilisant le vecteur logique en tant qu'indices

Code : Tout sélectionner

listLociPoly <- names(basic$allele_freq)[isPolymorph]


Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

Chrystelle Delord
Messages : 33
Enregistré le : 09 Avr 2013, 12:50

Re: [DEBUTANTE} fonction et lapply sur liste de matrices

Messagepar Chrystelle Delord » 30 Mai 2017, 14:05

Bonjour à vous deux et merci pour vos réponses :)


Le souci en fait, c'est que ces options effectuent le test sur l'ensemble des valeurs d'un tableau. Or, je suis obligée de faire le test ligne par ligne (d'où la boucle for que j'avais insérée dans ma petite fonction) vu que la somme des fréquences pour chaque colonne (allele 01 + 02) est égale à 1, et qu'une valeur inférieure à 0.05 sera forcément contrebalancée par une valeur supérieure à 0.95 dans la ligne adjacente.

En gros, dans l'exemple suivant :

Code : Tout sélectionner

> basic$allele_freq$HGY10119
        [,1] [,2]      [,3]   [,4]      [,5] [,6]  [,7] [,8]      [,9]     [,10]     [,11] [,12]
01 0.5555556  0.5 0.5526316 0.4375 0.5526316  0.5 0.475  0.6 0.5833333 0.7631579 0.6304348 0.575
02 0.4444444  0.5 0.4473684 0.5625 0.4473684  0.5 0.525  0.4 0.4166667 0.2368421 0.3695652 0.425

> basic$allele_freq$HGY10382
         [,1] [,2]       [,3]   [,4]       [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
01 0.94444444 0.96 0.97368421 0.9375 0.92105263 0.95 0.95 0.95    1     1     1     1
02 0.05555556 0.04 0.02631579 0.0625 0.07894737 0.05 0.05 0.05    0     0     0     0

> basic$allele_freq$HGY11802
         [,1] [,2]       [,3]   [,4]       [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
01 0.98 0.96 0.97368421 0.97 0.98 0.96 0.96 0.96   1     1     1     1
02 0.02 0.04 0.02631579 0.03 0.02 0.04 0.04 0.04    0     0     0     0


Le locus 10119 est conservé, les fréquences alléliques sont toutes supérieures à 0,05 (ou inférieures à 0,95).
Le locus 10382 est conservé : il est monomorphe (allele 01 fixé) dans certaines populations, mais reste polymorphe dans d'autres donc c'est OK.
Le locus 11802 par contre est éliminé car l'allèle 02 est en fréquence trop faible où que ce soit (allele 01 fixé partout).

La fonction

Code : Tout sélectionner

isPolymorph <- sapply(basic$allele_freq, function (itab) { any(itab>0.95) # any(itab<0.05) })
me permet de trouver des marqueurs monomorphes dans au moins une population, mais pas ceux qui sont monomorphes partout du coup.

La fonction

Code : Tout sélectionner

names(malist)[lapply(malist, max) < 2]
pourrait marcher mais malheureusement, comme elle porte sur l'ensemble du tableau et pas ligne par ligne, elle ne pourra pas me sortir de loci vu que par exemple pour mon 11802, toute valeur inférieure à 0,05 est contrebalancée par une valeur supérieure à 0,95. Désolée je ne suis peut-être pas très très claire :(...

C'est pour ça que pour moi, la seule façon de procéder était de d'abord appliquer une boucle for pour tester chaque ligne du tableau et voir si une des deux lignes possédait que des valeurs de 0.05 maximum (ou 0.95 minimum, peu importe), et si oui, stocker le nom du tableau dans la variable mono. Et puis répéter cette procédure sur tous mes tableaux en utilisant lapply.

Merci encore infiniment pour votre aide !! :-)

Chrystelle

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: [DEBUTANTE} fonction et lapply sur liste de matrices

Messagepar Gabriel Terraz » 30 Mai 2017, 14:12

Donc si j'ai bien compris, tu écartes les tableaux dont toutes les valeurs sont soit supérieures à 0.95, soit inférieures 0.05


Code : Tout sélectionner

names(malist)[sapply(malist, function(x) all(x < 0.05 | x > 0.95))]


C'est mieux ?

Chrystelle Delord
Messages : 33
Enregistré le : 09 Avr 2013, 12:50

Re: [DEBUTANTE} fonction et lapply sur liste de matrices

Messagepar Chrystelle Delord » 30 Mai 2017, 14:44

Merci beaucoup Gabriel, c'est exactement ce que je recherchais :) !! Effectivement, beaucoup plus facile qu'une fonction :)


Merci à tous pour vos réponses !
Chrystelle


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité