• Publicidad

Sustitución de patrones de una columna a otra

Perl aplicado a la bioinformática

Sustitución de patrones de una columna a otra

Notapor pacoparedes » 2012-08-10 18:10 @798

Hola, buenas tardes.

Por favor, pido su ayuda. Estoy parseando unos archivos que tienen la siguiente estructura:

archivo1.txt
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
P35720  327696
P35720  785395
P31039  281480
Q3T189  286840
Q95123  281481
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

archivo2.txt
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
P35720  P31039
P35720  Q3T189
P35720  Q95123
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


En el archivo1.txt la primera columna contiene el nombre de una proteína en formato UNIPROTKB, la segunda columna contiene su nombre equivalente en formato ENTREZ_GEN_ID.

El segundo archivo se trata de pares de proteínas cuyos nombres se encuentran en formato UNIPROTKB.

La intención es tomar el primer elemento de la primera columna contenida en el archivo2.txt y buscar su similar en la primera columna del archivo1.txt, y al encontrar la coincidencia sustituir el elemento contenido en la segunda columna del archivo2.txt, es decir su nombre equivalente en formato ENTREZ_GEN_ID. Y así sucesivamente hasta sustituir todas los nombres de las proteínas.

Para lo que he escrito el siguiente código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. #ejercicio1.pl
  3. my $arch = $ARGV[0];
  4. open( ARCH, $arch );
  5. my @equivalencias = <ARCH>;
  6. close ARCH;
  7. my $arch1 = $ARGV[1];
  8. open( ARCH1, $arch1 );
  9. my @red = <ARCH1>;
  10. close ARCH1;
  11.  
  12. foreach $i (@equivalencias) {
  13.     chomp($i);
  14.     @rengloneq = split( /\t/, $i );
  15.     for ( $j = 0; $j < @red; $j++ ) {
  16.         @renglonred = split( /\t/, $red[$j] );
  17.         if ( $rengloneq[0] =~ $renglonred[0] ) {
  18.             $red[$j] = "$rengloneq[1]\t$renglonred[1]\n";
  19.         }
  20.     }
  21.     chomp(@red);
  22.     for ( $j = 0; $j < @red; $j++ ) {
  23.         chomp($j);
  24.         @renglonred = split( /\t/, $red[$j] );
  25.         if ( $rengloneq[0] =~ $renglonred[1] ) {
  26.  
  27.             $red[$j] = "$renglonred[0]\t$rengloneq[1]\n";
  28.         }
  29.     }
  30. }
  31. chomp(@red);
  32. foreach $k (@red) {
  33.     chomp($k);
  34.     print "$k\n";
  35. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Pero ahora el problema es que como podemos observar en el archivo1.txt el nombre de una proteína en formato UNIPROTKB tiene más de un nombre equivalente en formato ENTREZ_GEN_ID.
archivo1.txt
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
P35720  327696
P35720  785395
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Por lo que yo necesito mis resultados de la siguiente forma. Dado el par:
archivo2.txt
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
P35720  P31039
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Obtener la siguiente substitución:
archivo_resultados.txt
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
327696  281480
785395  281480
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Y con mi código lo único que obtengo es:
archivo_resultados.txt
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
327696 281480
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Y el segundo par no lo puedo obtener. Es decir: no me duplica mi información. Es por eso que pido su ayuda y sugerencias para modificar mi código y solucionar este problema.

Gracias...
pacoparedes
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-10 17:03 @752

Publicidad

Re: Sustitución de patrones de una columna a otra

Notapor explorer » 2012-08-10 21:34 @940

Bienvenido a los foros de Perl en Español, pacoparedes.

La solución pasa por una doble búsqueda en las equivalencias, tanto en la primera como en la segunda columna:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #
  3. # ejercicio1.pl
  4.  
  5. my($archivo_equivalencias, $archivo_red) = @ARGV;
  6.  
  7. open my $EQUIVALENCIAS, $archivo_equivalencias  or die "ERROR: $!\n";
  8. my @equivalencias = <$EQUIVALENCIAS>;
  9. chomp @equivalencias;
  10. close $EQUIVALENCIAS;
  11.  
  12. open my $RED, $archivo_red                      or die "ERROR: $!\n";
  13. my @red = <$RED>;
  14. chomp @red;
  15. close $RED;
  16.  
  17. for my $red (@red) {                                           # para cada $red a decodificar
  18.     my($proteina1, $proteina2) = split " ", $red;              # extraemos las dos proteínas
  19.  
  20. #    print "Análisis para [$proteina1] [$proteina2]\n";
  21.  
  22.     for my $equ1 (@equivalencias) {                            # para cada equivalencia
  23.         my($uniprotkb1, $gen_id1) = split " ", $equ1;
  24.  
  25.         if ($uniprotkb1 eq $proteina1) {                       # que coincida con la primera proteína
  26.  
  27.             for my $equ2 (@equivalencias) {                    # para cada equivalencia
  28.                 my($uniprotkb2, $gen_id2) = split " ", $equ2;
  29.            
  30.                 if ($uniprotkb2 eq $proteina2) {               # que coincida con la segunda
  31.                     print "$gen_id1\t$gen_id2\n";              # pintamos las equivalencias
  32.                 }
  33.             }
  34.         }
  35.     }
  36. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

De forma más compacta, usando hash de array:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #
  3.  
  4. my($archivo_equivalencias, $archivo_red) = @ARGV;
  5.  
  6. my %equivalencias;
  7. open my $EQUIVALENCIAS, $archivo_equivalencias  or die "ERROR: $!\n";
  8. while (my $equivalencia = <$EQUIVALENCIAS>) {
  9.     chomp $equivalencia;
  10.     my($uniprotkb, $gen_id) = split " ", $equivalencia;
  11.     push @{ $equivalencias{ $uniprotkb } }, $gen_id;
  12. }
  13. close $EQUIVALENCIAS;
  14.  
  15. open my $RED, $archivo_red                      or die "ERROR: $!\n";
  16.  
  17. while (my $red = <$RED>) {
  18.     chomp $red;
  19.     my($proteina1, $proteina2) = split " ", $red;
  20.  
  21.     for my $gen_id1 (@{$equivalencias{$proteina1}}) {
  22.     for my $gen_id2 (@{$equivalencias{$proteina2}}) {
  23.         print "$gen_id1\t$gen_id2\n";
  24.     }}
  25. }
  26.  
  27. close $RED;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El doble bucle es necesario para recorrer los casos en los que la segunda columna tenga también más de una equivalencia entre los dos códigos. Si no fuese el caso, se podría quitar el bucle más interno. Y se ejecutaría más rápido, desde luego.
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: Sustitución de patrones de una columna a otra

Notapor pacoparedes » 2012-08-13 17:41 @778

Muchas gracias por la ayuda, explorer. Me funcionó muy bien...
pacoparedes
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-10 17:03 @752


Volver a Bioinformática

¿Quién está conectado?

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

cron