fusionner deux tableaux par une variable commune

Posthume
Invité n'ayant pas de compte PHPfrance

10 avr. 2010, 13:20

Bonjour tout le monde,

Voila je débute sur php et cela fait 2 jours que je bloque sur un tri de tableaux.
Je vous explique. Je dois parser deux fichiers de maniere a implémenter une base de données : Un fichier fasta et un fichier texte.
Une fois parsé, le fichier fasta me donne :
-> l'identifiant de la proteine
-> l'organisme
-> la sequence

Une fois parsé, le fichier texte me donne :
->l'identifiant de la proteine
->la base de données de référence
->le nom de la protéine

J'ai réussi a parser les 2 fichiers individuellements. Tout marche tres bien. Sauf que je veux faire un code unique ou je pourrai fusionner ces deux tableaux par l'identifiant de la proteine de maniere a ce qu'a chaque fois que l'identifiant est le meme dans les 2 fichiers, j'affiche tous les attributs des 2 fichiers soit :
Identifiant Proteine -> organisme, sequence, base de données de référence, nom de la proteine.

Voici mon code fasta :
<?php

//Parseur pour Leishmania

//Chargement du fichier fasta 
$fichier_Leishmania = 'LmajorAnnotatedProteins_TriTrypDB-2.0.fasta';

//On teste l'ouverture du fichier
if (!$f = fopen("$fichier_Leishmania","rb")) 
  { echo "Echec de l'ouverture de $fichier_Leishmania "; }

//On parcourt le fichier fasta
while (!feof($f))
{
 //On regarde si la ligne commence par un chevron
  if(preg_match('/^>/',$line))
    {
     $proteine = explode ('|', $line);

     //On recupere l'id de la proteine et le nom de l'organisme (qui est toujours le meme donc gain de temps en le definissant une fois!)
     echo "Identifiant : ".$proteine[1]."<br />\n"."Organisme : Leishmania_major"."<br />\n";

     //On saute une ligne pour recuperer la sequence
     $line = fgets($f);

     //Printage des lignes jusqu'au prochain chevron correspondantes a la sequence
     while ($line{0} != '>' && !feof($f))
        {
	// On lit une ligne et on passe à la ligne suivante tout en la printant

        echo ($sequence = $line);
        $line = fgets($f);
       
	}
    
    }
    else $line=fgets($f);
    echo "<br>";
    echo "<br>";
}

?>

Cela donne un resultat du genre :
identifiant : LmjF09.0003
Organisme : Leishmania_major
MGKESTVPTGCGAVNREVVLERMLVEEVAKRDDAERAAEELRKQMQLLKAEALDLRQARD LTKGSVLCTAAAHEGTAVSTVRDAECAESRESALKGENHRLRQLVKRQNALIDVLRRQKV LLEASAAINISVRDFDKQLEIHKV

Identifiant : LmjF09.0005
Organisme : Leishmania_major
MTCVTGDDTGVVKIWDISKSSGATLKFSFGEQSRKRAIMGMCWQDSSTSSVAFSSSNGVL SVLDINDYVVSSSVKANTVAGLPNAMSFVKGKLVVVSKDGEASIFSSDLTSSSCFSGNGP IDAVHIHRKFGMVAMGGRENDLCVYDLASDSLEEPVFKARNVRDHILDVPFPVFVTGACI VNPYVFATCTAYHQVRFYDRRSNDRPVQEFEISREIERRPTTMLQWNANKFLIGEASGDV HLYDTRRGFCSRAKLRGGVGSVRCMCKHPAGHQILGVTGLDRKARLYHVPTGKLLMSVYV KQKANCVLLDKQLPMRDRVAVFSGVVNTKQPEKANTLGDALWDDMDPVLDDLDEKAMVAD TVAENRRKVQRKE


Voici mon code texte :
<?php

//Parseur pour Leishmania

//Chargement du fichier texte
$fichier_LeishmaniaNom = 'LmajorInterpro_TriTrypDB-1.1.txt';

//On teste l'ouverture du fichier
if (!$fp = fopen("$fichier_LeishmaniaNom","rb")) 
  { echo "Echec de l'ouverture de $fichier_LeishmaniaNom "; }

//On parcourt le fichier texte
while (!feof($fp))
{
  $line=fgets($fp);
  $nom=preg_split('/\t/', $line, -1);
  if(preg_match('/\D/',$nom[3]))
    { echo "IdProteine : ".$nom[0]."<br />\n"."BD de reference : ".$nom[1]."<br />\n"."NomProteine : ".$nom[3];} 

  else {echo "IdProteine : ".$nom[0]."<br />\n"."BD de reference : ".$nom[1]."<br />\n"."NomProteine : None";}  

  echo "<br>\n";
  echo "<br>\n";	 

}

ce qui donne comme resultat un truc du genre :
IdProteine : LmjF36.6990
BD de reference : PFAM
NomProteine : zf-C2H2

IdProteine : LmjF36.6990
BD de reference : PFAM
NomProteine : MOZ_SAS

Voila ce qui est commun aux deux fichiers, c'est l'identifiant de la proteine et je voudrais recuperer tous les attributs pour en faire un tuple unique. J'ai essaye avec array_merge mais cela ne marche pas.

Merci a tous ceux qui pourront m'aider.

Mammouth du PHP | 661 Messages

10 avr. 2010, 14:43

ce que tu dois faire, c'est, premierement, monter un tableau avec le premier fichier !

de la forme :

Code : Tout sélectionner

$array=array() ; foreach (line du tableau) $array [$identifiant] = array( key => value, ....) //ensuite, tu vas remplir ce tableau avec les données du second fichier foreach (lines of second file) if (isSet($array [$identifiant_2])) $array [$identifiant] = array_merge($array [$identifiant_2], array(keyTbl2 =>value_2, ...)); else $array [$identifiant_2] = array(keyTbl2 =>value_2, ...);
après au niveau de la structure des boucles ou autre, tu fais comme tu veux, là je te donne juste la méthodologie ;)

pour l'afficher, il te suffira donc de faire :
foreach ($array as $idProteine => $arrayValues ){
  echo "IdProteine : $idProteine <br>";
  foreach ($arrayValues as $k => $v)
    echo "$k : $v <br>";
}

@+

Posthume
Invité n'ayant pas de compte PHPfrance

10 avr. 2010, 15:44

Bonjour Nours312 et merci beaucoup de ta reponse.

J'ai bien essaye de faire quelque chose comme ce que tu viens d'ecrire. Le probleme c'est que cela m'affiche les resultats des 2 fichiers mais de maniere desordonnee (chaque nom de proteine du second fichier ne correspond pas a l'identifiant du 1er fichier tu comprends?)

J'ai cree un tableau dans le 1er fichier:
$listeProteine = array ( 'Identifiant' => $proteine[1], 'Organisme' => 'Plasmodium_falciparum_3D7', 'Sequence' => $sequence) ;
J'ai cree un tableau dans le second fichier (mais la j'ai une condition donc dois je faire deux tableaux differents?):
   if  (preg_match('/\D/',$nom[3])) 
  
            {$listeNom = array ('Identifiant' => $nom[0], 'BD de reference' => $nom[1], 'NomProteine' => $nom[3]) ;}

           else 

             { $listeNom = array ('Identifiant' => $nom[0], 'BD de reference' => $nom[1], 'NomProteine' => 'None') ;}
         

Puis la je parcours les deux tableaux et mets une condition que si identifiant_1er fichier === identifiant_2eme fichier, alors j'affiche les attributs des deux fichiers mais cela ne marche pas.

Je ne comprends pas tres bien la 2eme partie de ton algo:
if (isSet($array [$identifiant_2]))
$array [$identifiant] = array_merge($array [$identifiant_2], array(keyTbl2 =>value_2, ...));
else
$array [$identifiant_2] = array(keyTbl2 =>value_2, ...);
Tu crees le tableau du 2eme fichier ($array[$identifiant_2] et tu fais un array_merge mais a quoi sert
array(keyTbl2 =>value_2, ...))
dans la 2eme ligne?
Autre chose, dois je faire ces foreach alors que les 2 fichiers sont ouverts?

Merci pour tout encore.

Mammouth du PHP | 661 Messages

10 avr. 2010, 17:06

oui, par ce qui faut que tu créé tes tableau avec une clé commune !

$listeProteine[$proteine[1]] = array ( 'Organisme' => 'Plasmodium_falciparum_3D7', 'Sequence' => $sequence) ;

dans ton second fichier tu fais pareil :

$listeNom = array ('Identifiant' => $nom[0], 'BD de reference' => $nom[1], 'NomProteine' => $nom[3]);
remplacé par :
$listeProteine[$nom[0]] = array_merge(isSet($listeProteine[$nom[0]]) ? $listeProteine[$nom[0]] : array() , array ('BD de reference' =>  $nom[1], 'NomProteine'  => (preg_match('/\D/',$nom[3])) ? $nom[3] : 'None')) ;
ou un truc du genre ^^
tu aura ensuite un seul tableau multi dimensionnel dans lequel se trouverons toutes tes données ...

ViPHP
ViPHP | 1996 Messages

10 avr. 2010, 20:30

Tiens moi le biologiste ch'ui tombé la dessus :
http://www.developpez.net/forums/d90548 ... le-unique/

Ca me fait marré c'est tout... :wink:
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

Posthume
Invité n'ayant pas de compte PHPfrance

10 avr. 2010, 20:34

Merci bien Nours312, je vais essayer de faire ce que tu m'as dit maintenant.

Posthume
Invité n'ayant pas de compte PHPfrance

10 avr. 2010, 20:38

Tiens moi le biologiste ch'ui tombé la dessus :
http://www.developpez.net/forums/d90548 ... le-unique/

Ca me fait marré c'est tout... :wink:

Je ne vois pas vraiment ce qu'il y a de marrant a demander de l'aide sur plusieurs forums surtout quand on est debutant 8-| mais bon si cela te fait rire et bein ma foi profites-en hein, c'est gratuit :!:

Posthume
Invité n'ayant pas de compte PHPfrance

10 avr. 2010, 22:41

Alors j'ai essaye de faire comme tu m'as montré mais le code ne m'affiche que les resultats du second fichier a savoir l'identifiant, le nom et la base de données de référence. Il ne m'affiche pas l'organisme et la séquence correspondante qui se trouvent dans le 1er fichier.

Voila ce que j'ai fait:
//On parcourt le fichier fasta
while (!feof($f))
{
 //On regarde si la ligne commence par un chevron
  if(preg_match('/^>/',$line))
    {
     $proteine = explode ('|', $line);

     //On saute une ligne pour recuperer la sequence
     $line = fgets($f);

     //Printage des lignes jusqu'au prochain chevron, correspondantes a la sequence
     while ($line{0} != '>' && !feof($f))
        {
	// On lit une ligne et on passe à la ligne suivante tout en la printant

        $sequence = $line;
        $line = fgets($f);
            
        $listeProteine[$proteine[1]] = array ();
        foreach ($listeProteine[$proteine[1]] as $contenu)
        {$listeProteine[$proteine[1]] = array ( 'Organisme' => 'Plasmodium_falciparum_3D7', 'Sequence' => $sequence) ;}

	}
   
    }
    else $line=fgets($f);

    //On parcourt le fichier texte
    while (!feof($fp))
    {

     $LINE=fgets($fp);
     $nom=preg_split('/\t/', $LINE, -1);
         
         if (isSet($listeProteine [$nom[0]]))
           {$listeProteine [$proteine[1]] = array_merge($listeProteine [$nom[0]], array('BD de reference' =>  $nom[1], 'NomProteine'  => (preg_match('/\D/',$nom[3])) ? $nom[3] : 'None'));}
         else
           {$listeProteine [$nom[0]] = array('BD de reference' =>  $nom[1], 'NomProteine'  => (preg_match('/\D/',$nom[3])) ? $nom[3] : 'None'); }  
 
     foreach ($listeProteine as $proteine[1] => $listeProteineValues )
         {
          echo "IdProteine : $proteine[1] <br>";
          foreach ($listeProteineValues as $k => $v)
                {echo "$k : $v <br>";}
        }

    }

 
}
J'ai vraiment du mal avec ces tableaux. Merci a toute ame genereuse qui voudra bien m'eclaircir car la je vois pas :oops:

Mammouth du PHP | 661 Messages

11 avr. 2010, 00:58

heuu ..; je t'ai pas dit ça non plus ^^
$listeProteine = array();
//On parcourt le fichier fasta
while (!feof($f))
{
 //On regarde si la ligne commence par un chevron
  if(preg_match('/^>/',$line))
    {
     $proteine = explode ('|', $line);

     //On saute une ligne pour recuperer la sequence
     $line = fgets($f);

     //Printage des lignes jusqu'au prochain chevron, correspondantes a la sequence
     while ($line{0} != '>' && !feof($f))
        {
        // On lit une ligne et on passe à la ligne suivante tout en la printant

        $sequence = $line;
        $line = fgets($f);
           
        $listeProteine[$proteine[1]] = array ( 'Organisme' => 'Plasmodium_falciparum_3D7', 'Sequence' => $sequence) ;
// premier fichier, on rempli !
        }
   
    }
    else $line=fgets($f);

    //On parcourt le fichier texte
    while (!feof($fp))
    {

     $LINE=fgets($fp);
     $nom=preg_split('/\t/', $LINE, -1);

     $listeProteine[$nom[0]] = array_merge((isSet($listeProteine[$nom[0]])) ? $listeProteine[$nom[0]] : array(), array('BD de reference' =>  $nom[1], 'NomProteine'  => (preg_match('/\D/',$nom[3])) ? $nom[3] : 'None'));
 //second fichier => on joins !!

    }

 
}
//là on affiche !
     foreach ($listeProteine as $idproteine => $listeProteineValues )
         {
          echo "IdProteine : $idproteine <br>";
          foreach ($listeProteineValues as $k => $v)
                {echo "$k : $v <br>";}
        }


Eléphant du PHP | 170 Messages

11 avr. 2010, 08:00

Bonjour,

une autre façon de faire :
Je dois parser deux fichiers de maniere a implémenter une base de données
Une fois parsé, le fichier fasta me donne :
-> l'identifiant de la proteine
-> l'organisme
-> la sequence
dans la boucle, tu fais un "INSERT" dans ta table avec ces 3 données.

Une fois parsé, le fichier texte me donne :
->l'identifiant de la proteine
->la base de données de référence
->le nom de la protéine
dans la boucle, tu fais un "UPDATE" de l'enregistrement qui a le même "identifiant de la proteine" avec les 2 autres données.

Posthume
Invité n'ayant pas de compte PHPfrance

11 avr. 2010, 09:46

heuu ..; je t'ai pas dit ça non plus ^^
$listeProteine = array();
//On parcourt le fichier fasta
while (!feof($f))
{
 //On regarde si la ligne commence par un chevron
  if(preg_match('/^>/',$line))
    {
     $proteine = explode ('|', $line);

     //On saute une ligne pour recuperer la sequence
     $line = fgets($f);

     //Printage des lignes jusqu'au prochain chevron, correspondantes a la sequence
     while ($line{0} != '>' && !feof($f))
        {
        // On lit une ligne et on passe à la ligne suivante tout en la printant

        $sequence = $line;
        $line = fgets($f);
           
        $listeProteine[$proteine[1]] = array ( 'Organisme' => 'Plasmodium_falciparum_3D7', 'Sequence' => $sequence) ;
// premier fichier, on rempli !
        }
   
    }
    else $line=fgets($f);

    //On parcourt le fichier texte
    while (!feof($fp))
    {

     $LINE=fgets($fp);
     $nom=preg_split('/\t/', $LINE, -1);

     $listeProteine[$nom[0]] = array_merge((isSet($listeProteine[$nom[0]])) ? $listeProteine[$nom[0]] : array(), array('BD de reference' =>  $nom[1], 'NomProteine'  => (preg_match('/\D/',$nom[3])) ? $nom[3] : 'None'));
 //second fichier => on joins !!

    }

 
}
//là on affiche !
     foreach ($listeProteine as $idproteine => $listeProteineValues )
         {
          echo "IdProteine : $idproteine <br>";
          foreach ($listeProteineValues as $k => $v)
                {echo "$k : $v <br>";}
        }



Autant pour moi j'ai du mal comprendre.
Mais je viens d'essayer ton code tel que tu me l'as donne et cela donne helas le meme resultat que ce que j'ai fait precedemment. Il m'affiche en premier les donnees du second fichier puis plus loin il m'affiche les donnees du 1er fichier sauf qu'ici il n'y a que la 1ere ligne de la sequence qui apparait #-o

Je suis perdue :cry:

ps:excusez moi pour l'absence d'accents, c'est un ordinateur qui n'en contient pas.

Posthume
Invité n'ayant pas de compte PHPfrance

11 avr. 2010, 09:49

Bonjour,

une autre façon de faire :
Je dois parser deux fichiers de maniere a implémenter une base de données
Une fois parsé, le fichier fasta me donne :
-> l'identifiant de la proteine
-> l'organisme
-> la sequence
dans la boucle, tu fais un "INSERT" dans ta table avec ces 3 données.

Une fois parsé, le fichier texte me donne :
->l'identifiant de la proteine
->la base de données de référence
->le nom de la protéine
dans la boucle, tu fais un "UPDATE" de l'enregistrement qui a le même "identifiant de la proteine" avec les 2 autres données.

Bonjour,

J'ai pense a faire cela sauf qu'etant donne les contraintes posees dans la table de donnees, si je fournit un tuple en premier qui ne contient pas certaines valeurs, tout le tuple sera supprime donc c'est un vrai casse tete.

Eléphant du PHP | 170 Messages

11 avr. 2010, 14:21

J'ai pense a faire cela sauf qu'etant donne les contraintes posees dans la table de donnees, si je fournit un tuple en premier qui ne contient pas certaines valeurs, tout le tuple sera supprime donc c'est un vrai casse tete.
Supposons que tu aies une table nommée "la_table" avec comme champs : identifiant_proteine, organisme, sequence, bdd_reference, nom_proteine

Tu affirmes que cette requête ne fonctionne pas ?
INSERT INTO la_table (identifiant_proteine, organisme, sequence) VALUES ('LmjF09.0003', 'Leishmania_major', 'MGKESTVPTG...etc...')
Ou bien je n'ai pas compris ce que tu voulais dire ?

Posthume
Invité n'ayant pas de compte PHPfrance

11 avr. 2010, 16:48

J'ai pense a faire cela sauf qu'etant donne les contraintes posees dans la table de donnees, si je fournit un tuple en premier qui ne contient pas certaines valeurs, tout le tuple sera supprime donc c'est un vrai casse tete.
Supposons que tu aies une table nommée "la_table" avec comme champs : identifiant_proteine, organisme, sequence, bdd_reference, nom_proteine

Tu affirmes que cette requête ne fonctionne pas ?
INSERT INTO la_table (identifiant_proteine, organisme, sequence) VALUES ('LmjF09.0003', 'Leishmania_major', 'MGKESTVPTG...etc...')
Ou bien je n'ai pas compris ce que tu voulais dire ?

Oui c'est exactement cela, les champ BD de reference et nom_proteine doivent etre obligatoirement renseignes (NOT NULL en sql) pour que le tuple soit pris en consideration et insere dans la BD sinon il est tout simplement ignore. J'ai deja essaye crois moi. C'est pour cela que j'essaie de faire un code unique de maniere a recuperer toutes les donnees d'un coup pour en faire un tuple unique. C'est la toute la difficulte :(

'