• Publicidad

Unir dos tablas

Perl aplicado a la bioinformática

Unir dos tablas

Notapor alemanmd » 2014-01-11 21:54 @954

¿Qué tal? Tengo dos tablas en forma de tabulador y tengo que unirlas para reunir la información de ambas tablas en un solo archivo. Una de las columnas es el ID de la proteína y utilizo el ID para comparar las líneas de las dos tablas; si son iguales entonces imprimo las columnas de ambas tablas.

Funciona si solo quiero las que existen, pero también me interesa que las que no existan se imprima el ID y las columnas de la primera tabla además de otra indicación que diga "no hit"; esta segunda parte es la que no logro hacer funcionar en mi programa.

Este es mi código:
Sintáxis: (extractor_filas.pl) [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/local/bin/perl.
  2.  
  3. # Este programa compara un id de una lista con el de una segunda lista, si el ID es igual entonces imprime las variables que tu desees
  4. # funciona para  dos listas y los archivos se pueden usar sin importar el lugar (1.txt vs 2.txt o bien 2.txt vs 1.txt)
  5.  
  6. # uso:
  7. # perl extract_filas_lista.pl file1 file2
  8. # output: lista.txt
  9.  
  10. use strict;
  11.  
  12. my $file1 = $ARGV[0];                  # ingresa un archivo que se llamara file1
  13. my $file2 = $ARGV[1];                  # ingresa un archivo que se llamara file2
  14.  
  15. #use Tie::IxHash;                              # este módulo es el que permite almacenar la lista en el hash
  16. #tie my %filas, 'Tie::IxHash';                 # manteniendo el orden en el que fue ingresado
  17.  
  18. my %filas;
  19. my $n = 0;
  20. my $numero1;
  21. my @b;
  22.  
  23. open( LISTA, "$file1" ) || die("No puedo abrir $file1\n");
  24.  
  25. #open (RAS, ">lista2.txt") || die ("no puedo abrir secuencias.fasta\n");
  26.  
  27. while ( my $linea = <LISTA> ) {
  28.     chomp($linea);
  29.  
  30.     #if ($linea =~ /(\w+\-\d+)/){
  31.     if ( $linea =~ /(\d+)/ ) {
  32.         chomp($linea);
  33.         @b               = split( /\t/, $linea );    # este patrón se puede cambiar para adaptarse a tus necesidades
  34.         $numero1         = $b[0];
  35.         $filas{$numero1} = 0;
  36.         $n++;
  37.  
  38.         #print RAS "Ta-$numero1\n";
  39.         #print  "$numero1\n";
  40.     }
  41. }
  42. close(LISTA);
  43.  
  44. open( LISTA2, "$file2" )       || die("No puedo abrir $file2\n");
  45. open( RES,    ">iguales.txt" ) || die("no puedo abrir secuencias.fasta\n");
  46.  
  47. # tie my %filas2, 'Tie::IxHash';
  48.  
  49. my %filas2;
  50. my $n1 = 0;
  51. my $numero1;
  52. my $var1;
  53. my $var2;
  54. my @a;
  55. my $iguales = 0;
  56. while ( my $linea = <LISTA2> ) {
  57.     chomp($linea);
  58.  
  59.     #if ($linea =~ /gi/){
  60.     if ( $linea =~ /(\d+)/ ) {
  61.  
  62.         #if ($linea =~ /(\w+\-\d+)/) {     # este patrón se puede cambiar para adaptarse a tus necesidades
  63.         my @a = split( /\t/, $linea );
  64.         $var1          = $a[0];
  65.         $var2          = $a[1];
  66.         $filas2{$var1} = $linea;
  67.         $n1++;
  68.  
  69.         #print ("$var1\n");
  70.         #print ("$var2\n");
  71.         if ( exists $filas{ $a[0] } ) {
  72.  
  73.             #print "$filas{$a[0]}\n";
  74.             #print RES "$a[1]\t$var1\n";
  75.             $iguales++;
  76.  
  77.             #print   "$b[0]\t$b[1]\t$b[2]\t$b[3]\t$b[4]\t$b[5]\t$b[6]\t$a[2]\t$a[3]\t$a[4]\t$a[5]\t$a[6]\n";
  78.             print RES "$b[0]\t$b[1]\t$b[2]\t$b[3]\t$b[4]\t$b[5]\t$b[6]\t$a[2]\t$a[3]\t$a[4]\t$a[5]\t$a[6]\n";
  79.  
  80.             #print   "$linea\n";
  81.         }
  82.         unless ( exists $filas{ $a[0] } ) {
  83.             print "$b[0]\t$b[1]\t$b[2]\t$b[3]\t$b[4]\t$b[5]\t$b[6]\t$a[2]\t$a[3]\t$a[4]\t$a[5]\t$a[6]\n";
  84.         }
  85.     }
  86. }
  87. print "\t\tRESULTADOS\n";
  88. print "tienes $n ID en tu lista $ARGV[0]\n";
  89. print "Se identificaron $iguales ID de la lista $ARGV[0] en  la lista $ARGV[1]\n";
  90.  
  91. close(LISTA);
  92. close(RES);
  93.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


gracias, espero puedan ayudarme.
Adjuntos
list2.txt
Esta es la tabla 2
(1.97 KiB) 138 veces
list1.txt
Esta es la tabla 1
(127.84 KiB) 141 veces
alemanmd
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-11-28 20:16 @886

Publicidad

Re: Unir dos tablas

Notapor explorer » 2014-01-12 00:41 @070

Primero, decir que este código viene del hilo Comparar dos listas sin que cambie la posición publicado anteriormente.

Luego, decir que, en este caso, es mejor leer y almacenar primero el segundo archivo, ya que luego, al recorrer el primer archivo, con independencia de si hay o no coincidencia, sacaremos todas las líneas del primer archivo. Al hacerlo así, el mismo bucle de lectura se convierte en el de escritura del resultado.

Esta es una posible solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. #
  3. # Unir tablas de predicciones extracelulares
  4. # Joaquín Ferrero, 2014.01.12
  5. #
  6. # Este programa lee dos archivos con datos en columnas, con un tabulador como delimitador.
  7. #
  8. # Los dos archivos contienen un ID numérico en la primera columna.
  9. #
  10. # El objetivo es sacar los datos del primer archivo unidos a los datos del segundo archivo, en aquellas líneas coincidentes por ID,
  11. # o los datos del primer archivo, junto con el texto 'no hit', que no coincidan con ningún ID del segundo archivo.
  12. #
  13. # Uso:
  14. #       perl join_predictions.pl file1 file2
  15. #
  16. # Salida:
  17. #       Archivo list.txt
  18. #
  19.  
  20. use v5.16;
  21. use autodie;
  22.  
  23.  
  24. ## Comprobación de los argumentos de entrada
  25. @ARGV == 2 or die "Uso: perl $0 file1 file2\n";
  26.  
  27. my($file1, $file2) = @ARGV;
  28.  
  29. -f $file1  or die "ERROR: No encuentro el archivo [$file1]\n";
  30. -f $file2  or die "ERROR: No encuentro el archivo [$file2]\n";
  31.  
  32.  
  33. ## Lectura del archivo segundo (el dependiente)
  34. open my $fh2, '<', $file2;
  35.  
  36. my %file2;
  37.  
  38. while (my $linea = <$fh2>) {
  39.     chomp $linea;
  40.  
  41.     my($id2, @datos2) = split /\t/, $linea;
  42.  
  43.     $file2{ $id2 } = [ @datos2 ];
  44. }
  45.  
  46. close $fh2;
  47.  
  48.  
  49. ## Apertura del archivo de salida y del primer archivo (el independiente). Procesado
  50. open my $fh1, '<', $file1;
  51. open my $fh3, '>', 'list.txt';
  52.  
  53. my $n       = 0;
  54. my $iguales = 0;
  55.  
  56. while (my $linea = <$fh1>) {
  57.     chomp $linea;
  58.  
  59.     my($id1, @datos1) = split /\t/, $linea;
  60.  
  61.     next if $id1 !~ /^\d+$/;            # pasa a la siguiente si el ID no es un número (evitar líneas de cabecera)
  62.  
  63.     my @datos = ($id1, @datos1);        # composición de los datos definitivos que imprimiremos
  64.  
  65.     if ($file2{$id1}) {                 # si existe alguna línea en el segundo archivo con ese ID,
  66.         my @datos2 = @{$file2{$id1}};   # recuperamos los datos del segundo archivo
  67.         push @datos, @datos2[1..5];     # y los unimos a los del primero
  68.  
  69.         $iguales++;
  70.     }
  71.     else {                              # si no, no hay coincidencia, así que informamos de ello
  72.         push @datos, 'no hit';
  73.     }
  74.  
  75.     say $fh3 join "\t", @datos;         # y los sacamos fuera
  76.  
  77.     $n++;
  78. }
  79.  
  80. close $fh1;
  81. close $fh3;
  82.  
  83. say "\t\tRESULTADOS";
  84. say "Tienes $n ID en tu lista $file1";
  85. say "Se identificaron $iguales ID de la lista $file1 en la lista $file2";
  86.  
  87. __END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

La salida en pantalla, con los archivos que has adjuntado, es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
                RESULTADOS
Tienes 2624 ID en tu lista lista1.txt
Se identificaron 26 ID de la lista lista1.txt en la lista lista2.txt
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Las primeras líneas del archivo de salida son:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
340513771       124295  Treesei EGR44057.1      20      0.917   YES     no hit
340513772       82662   Treesei EGR44058.1      19      0.722   YES     7.00E-088       Sm7     AAZ80394        Trichoderma virens      87.15490196
340513779       71092   Treesei EGR44064.1      22      0.679   YES     no hit
340513792       112649  Treesei EGR44075.1      29      0.506   YES     no hit
340513800       73102   Treesei EGR44082.1      18      0.728   YES     no hit
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Unir dos tablas

Notapor alemanmd » 2014-01-12 14:51 @660

Muchas gracias, explorer. Estoy trabajando con el código, ahora.

Me di cuenta con el código, también, que necesito actualizar mi versión de Perl. Estoy con eso para poder correr el código.

Por cierto, la indicación de qué hace en cada parte es genial, ¡¡así aprendo más fácil cómo está funcionando cada parte!!

¡ Saludos y muchas gracias de nuevo !
alemanmd
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2011-11-28 20:16 @886

Re: Unir dos tablas

Notapor explorer » 2014-01-12 15:46 @699

Bueno, puse un v5.16, porque es la versión que tengo ahora en casa, pero con un v5.10, es más que suficiente.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados