• Publicidad

Recorrer dos arrays simultáneamente

Perl aplicado a la bioinformática

Recorrer dos arrays simultáneamente

Notapor estromboli » 2012-01-05 03:59 @207

¡Buenas!

Tengo un problema con un programa que estoy intentando hacer.

Tengo dos cadenas diferentes de ADN en dos arrays. Quiero recorrerlos para contar cuántas posiciones tienen la misma base, en cuántas hay transversiones y en cuántas, transiciones.

Al principio pretendí hacer un foreach() con los dos arrays, pero no se puede, ¿verdad?.

Ahora he hecho un foreach() recorriendo uno de los arrays y otro dentro recorriendo el otro array. Claramente está mal porque me da un número que no tiene sentido. Dejo aquí lo que tengo hecho, porque la verdad es que no sé seguir. Muchas gracias.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #abrimos delfin.txt y lo metemos en @delfin
  3. print "Introduzca primer archivo: \n";
  4. $file1 = <STDIN>;
  5. chomp $file1;
  6. unless ( open( DELFIN, $file1 ) ) {
  7.     print "No se puede abrir el archivo.\n";
  8.     exit;
  9. }
  10. @delfin = <DELFIN>;
  11. close DELFIN;
  12. $file1 = join( '', @delfin );          #pasamos secuencia a una cadena.
  13. $file1 =~ s/\s//g;
  14. @delfin = split( '', $file1 );
  15.  
  16. #abrimos foca.txt y lo metemos en @foca
  17. print "Introduzca segundo archivo: \n";
  18. $file2 = <STDIN>;
  19. chomp $file2;
  20. unless ( open( FOCA, $file2 ) ) {
  21.     print "No se puede abrir el archivo.\n";
  22.     exit;
  23. }
  24. @foca = <FOCA>;
  25. close FOCA;
  26. $file2 = join( '', @foca );
  27. $file2 =~ s/\s//g;
  28. @foca = split( '', $file2 );
  29. print "Primer archivo:\n",  "@delfin\n";
  30. print "Segundo archivo:\n", "@foca\n";
  31. $count = 0;
  32.  
  33. foreach $based (@delfin) {
  34.     foreach $basef (@foca) {
  35.         if ( $based eq $basef ) {
  36.             ++$count;
  37.         }
  38.     }
  39. }
  40. print "$count\n";
  41.  
  42. #consigo que cuente pero me da un numero demasiado grande.Problema con el bucle foreach seguro.Creo que compara la primera base de @delfin con cada una de las de @foca
  43.  
  44. $countv = 0;
  45. foreach $based (@delfin) {
  46.     foreach $basef (@foca) {
  47.         if ( $based eq 'a' ) {
  48.             if ( $basef eq 'g' ) {
  49.                 ++$countv;
  50.             }
  51.         }
  52.         if ( $based eq 'g' ) {
  53.             if ( $basef eq 'a' ) {
  54.                 ++$countv;
  55.             }
  56.         }
  57.         if ( $based eq 't' ) {
  58.             if ( $basef eq 'c' ) {
  59.                 ++$countv;
  60.             }
  61.         }
  62.         if ( $based eq 'c' ) {
  63.             if ( $basef eq 't' ) {
  64.                 ++$countv;
  65.             }
  66.         }
  67.     }
  68. }
  69.  
  70. print "$countv\n";
  71.  
  72. $counts = 0;
  73. foreach $based (@delfin) {
  74.     foreach $basef (@foca) {
  75.         if ( $based eq 'a' || 'g' ) {
  76.             if ( $basef eq 'c' || 't' ) {
  77.                 ++$counts;
  78.             }
  79.         }
  80.         if ( $based eq 'c' || 't' ) {
  81.             if ( $basef eq 'a' || 'g' ) {
  82.                 ++$counts;
  83.             }
  84.         }
  85.     }
  86. }
  87.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2012-01-05 18:58 @832, editado 1 vez en total
Razón: Formateado de código con Perltidy y poner marcas Perl
estromboli
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2011-12-30 11:20 @513

Publicidad

Re: Recorrer dos arrays simultáneamente

Notapor explorer » 2012-01-05 19:12 @842

Bienvenido a los foros de Perl en español, estromboli.

Sí que se pueden recorrer dos arrays a la vez.

Suponiendo que los dos tienen la misma longitud, solo tienes que acceder con el mismo índice:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for (my $i = 0; $i < @delfin; $i++) {
  2.     my $based = $delfin[$i];
  3.     my $basef = $foca  [$i];
  4.  
  5.     # aquí hacemos la comparación
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Otra opción es con el módulo List::MoreUtils:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use List::MoreUtils 'each_array';
  2.  
  3. my $ea = each_array(@delfin, @foca);
  4.  
  5. while (my($based, $basef) = $ea->()) {
  6.  
  7.     # aquí, comparamos
  8. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Este último tiene la ventaja de que no está limitado a solo dos array.

Por otra parte, ¿cuál es la definición de una transversión y de una transición? Viendo el código, me temo que algunas comparaciones están mal...
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: Recorrer dos arrays simultáneamente

Notapor estromboli » 2012-01-06 10:42 @488

Pues una transversión es el cambio de una purina por una pirimidina y una transición el de una purina o pirimidina a purina o pirimidina diferentes.

¿Está mal el código en concepto o en cuanto a manera de programar?
estromboli
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2011-12-30 11:20 @513

Re: Recorrer dos arrays simultáneamente

Notapor explorer » 2012-01-06 11:25 @517

Si me lo pones en forma de bases, lo entiendo mejor (no soy bioinformático del todo) :)

Los problemas que veo son del tipo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         if ( $based eq 'a' || 'g' ) {
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

creo que en realidad quieres poner
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         if ( $based eq 'a'  or  $based eq 'g' ) {
Coloreado en 0.001 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: Recorrer dos arrays simultáneamente

Notapor estromboli » 2012-01-06 11:50 @535

¡Sí, sí! Es lo que quería poner: que si esa base en concreto es 'a' o 'g', entre en el if().

¡Gracias!
estromboli
Perlero nuevo
Perlero nuevo
 
Mensajes: 3
Registrado: 2011-12-30 11:20 @513

Re: Recorrer dos arrays simultáneamente

Notapor explorer » 2012-01-07 11:39 @527

Las líneas 47 a 66 pueden quedar reducidas a
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         ++$countv
  2.             if ($based eq 'a'  and  $basef eq 'g')
  3.             or ($based eq 'c'  and  $basef eq 't')
  4.             or ($based eq 'g'  and  $basef eq 'a')
  5.             or ($based eq 't'  and  $basef eq 'c')
  6.             ;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Las líneas 75 a 85 pueden quedar reducidas a:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         ++$counts
  2.             if (    ($based eq 'a' or $based eq 'g')
  3.                 and
  4.                     ($basef eq 'c' or $basef eq 't')
  5.             )
  6.             or (    ($based eq 'c' or $based eq 't')
  7.                 and
  8.                     ($basef eq 'a' or $basef eq 'g')
  9.             )
  10.             ;
Coloreado en 0.001 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


Volver a Bioinformática

¿Quién está conectado?

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

cron