• Publicidad

Posiciones de un array

Perl aplicado a la bioinformática

Posiciones de un array

Notapor angelluigi » 2016-11-16 08:55 @413

Buenas.

Me están pidiendo que diga las posiciones en un array que presenten el valor mínimo. Ando un poco liado con esto. Si alguien me puede ayudar...

Muchas gracias.
angelluigi
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2016-11-16 08:52 @411

Publicidad

Re: Posiciones de un array

Notapor explorer » 2016-11-16 18:09 @798

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

Es un problema algo complejo, ya que hay que recordar las posiciones que vamos encontrando, con el valor mínimo.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.20;
  3.  
  4. my @array = map { 10 + int rand 90 } 1 .. 100;
  5.  
  6. #say "@array";
  7.  
  8. my @posiciones_minimo;
  9. my $valor_minimo = 10E10;
  10.  
  11. while(my($i, $valor) = each @array) {
  12.     if ($valor_minimo > $valor) {
  13.         $valor_minimo = $valor;
  14.         @posiciones_minimo = ();
  15.     }
  16.  
  17.     if ($valor_minimo == $valor) {
  18.         push @posiciones_minimo, $i;
  19.     }
  20. }
  21.  
  22. say "Mínimo encontrado: $valor_minimo";
  23. say "Posiciones en las que se encuentra: @posiciones_minimo";
  24.  
  25. __END__
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Una posible ejecución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$./kk.pl
Mínimo encontrado: 10
Posiciones en las que se encuentra: 43 59 90
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Bueno, al final, no es tan complejo... con apenas 5 líneas principales lo resolvemos.

La explicación del funcionamiento te lo dejo como deberes para casa.

Naturalmente, se puede hacer de otras formas.
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: Posiciones de un array

Notapor angelluigi » 2016-11-16 19:22 @849

Muchas gracias, acabo de empezar el master en bioinformática y todavía ando un poco verde.

Lo he probado y la solución concuerda perfectamente. Más o menos creo que lo he entendido. Lo que pasa es que no he visto el bucle while() ... each(), que has usado. Yo he sacado el valor mínimo con un foreach y pensaba sacar la posición, o sea, el índice, con un bucle for.

Te dejo el código para ver si puedes sacarlo con un bucle for, gracias y perdón por las molestias.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @skew = ();
  2.  
  3. $contador_G = 0;
  4. $contador_C = 0;
  5. $min_skew   = 0;
  6.  
  7. $secuencia = "CCTATCGGTGGATTAGCATGTCCCTGTACGTTTCGCCGCGAACTAGTTCACACGGCTTGATGGCAAATGGTTTTTCCGGCGACCGTAATCGTCCACCGAG";
  8.  
  9. for ( my $i = 0; $i < ( length $secuencia ); $i++ ) {
  10.     $base = substr( $secuencia, $i, 1 );
  11.     if    ( $base =~ /C/ ) { $contador_C = $contador_C + 1; }
  12.     elsif ( $base =~ /G/ ) { $contador_G = $contador_G + 1; }
  13.     my $diferencia_GC = $contador_G - $contador_C;
  14.  
  15.     push @skew, $diferencia_GC;
  16.     foreach (@skew) {
  17.         if ( $_ < $min_skew ) { $min_skew = $_; }
  18.  
  19.     }
  20.  
  21. }
  22.  
  23. $skew = join( '', (@skew) );
  24. print $skew, "\n\n\n";
  25.  
  26. $valor_minimo = $min_skew;
  27.  
  28. my @posiciones_minimo;
  29.  
  30. while ( my ( $i, $valor ) = each @skew ) {
  31.     if ( $valor_minimo > $valor ) {
  32.         $valor_minimo      = $valor;
  33.         @posiciones_minimo = ();
  34.     }
  35.  
  36.     if ( $valor_minimo == $valor ) {
  37.         push @posiciones_minimo, $i;
  38.     }
  39. }
  40.  
  41. print @posiciones_minimo;
  42.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2016-11-17 17:39 @777, editado 2 veces en total
Razón: Poner marcas de código Perl
angelluigi
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2016-11-16 08:52 @411

Re: Posiciones de un array

Notapor explorer » 2016-11-17 18:28 @811

No necesitas hacer dos bucles, ya que con uno te vale, ya que estás recorriendo toda la secuencia:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2.  
  3. my @skew;
  4.  
  5. my $contador_G;
  6. my $contador_C;
  7. my $min_skew   = length $secuencia;     # hay que inicializarlo a un valor alto o máximo
  8. my @posiciones_minimo;
  9.  
  10. my $secuencia = "CCTATCGGTGGATTAGCATGTCCCTGTACGTTTCGCCGCGAACTAGTTCACACGGCTTGATGGCAAATGGTTTTTCCGGCGACCGTAATCGTCCACCGAG";
  11.  
  12. for ( my $i = 0; $i < length $secuencia; $i++ ) {
  13.  
  14.     $base = substr $secuencia, $i, 1;
  15.  
  16.     if    ( $base eq 'C' ) { $contador_C++; }
  17.     elsif ( $base eq 'G' ) { $contador_G++; }
  18.  
  19.     my $diferencia_GC = $contador_G - $contador_C;
  20.  
  21.     push @skew, $diferencia_GC;
  22.  
  23.     if ($min_skew > $diferencia_GC) {
  24.         $min_skew = $diferencia_GC;     # tenemos un nuevo mínimo
  25.         @posiciones_minimo = ();        # reiniciamos el almacén de posiciones
  26.     }
  27.  
  28.     if ( $diferencia_GC == $min_skew ) {        # si es un mínimo,
  29.         push @posiciones_minimo, $i;            # recordamos su posición
  30.     }
  31. }
  32.  
  33. print join('|', @skew), "\n\n";         # -1|-2|-2|-2|-2|-3|-2|-1|-1|0|1|1|1|1|1|2|1|1|1|2|2|1|0|-1|-1|0|0|0|-1|0|0|0|0|-1|0|-1|-2|-1|-2|-1|-1|-1|-2|-2|-2|-1|-1|-1|-2|-2|-3|-3|-4|-3|-2|-3|-3|-3|-2|-2|-2|-1|0|-1|-1|-1|-1|-1|0|1|1|1|1|1|1|0|-1|0|1|0|1|1|0|-1|0|0|0|0|0|-1|0|0|-1|-2|-2|-3|-4|-3|-3|-2
  34.  
  35. print "Valor mínimo: $min_skew\n";     # Valor mínimo: -4
  36.  
  37. print "@posiciones_minimo\n";           # 52 96
  38.  
Coloreado en 0.003 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: Posiciones de un array

Notapor angelluigi » 2016-11-17 18:39 @818

Muchas gracias, lo acabo de probar y va perfecto.
angelluigi
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2016-11-16 08:52 @411

Re: Posiciones de un array

Notapor explorer » 2016-11-19 20:45 @906

Esta es otra versión, más corta, usando otra técnica.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.14;
  3.  
  4. my $secuencia = 'CCTATCGGTGGATTAGCATGTCCCTGTACGTTTCGCCGCGAACTAGTTCACACGGCTTGATGGCAAATGGTTTTTCCGGCGACCGTAATCGTCCACCGAG';
  5.  
  6. my %visto;
  7. my $contador = 0;
  8.  
  9. while ($secuencia =~ m/(?<letras_repetidas>(?|(?<letra>C)+|G+))/g) {
  10.     my $largo = length $+{letras_repetidas};
  11.  
  12.     $contador += $+{letra} eq 'C' ? -$largo : $largo;
  13.  
  14.     push @{$visto{ $contador }}, pos($secuencia);       # posiciones basadas en 0, pero terminan más allá,
  15.                                                         # así que es como si estuvieran basadas en 1
  16. }
  17.  
  18. #use Data::Dumper;
  19. #say Dumper \%visto;
  20.  
  21. my $minimo = (sort {$a <=> $b} keys %visto)[0];
  22.  
  23. say "Mínimo [$minimo] en las posiciones [@{$visto{$minimo}}]";         # Mínimo [-4] en las posiciones [53 97]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

La idea se basa en localizar los grupos de letras 'C' y 'G', contando las veces que se repiten, y la posición en la que se encuentran.
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: Posiciones de un array

Notapor angelluigi » 2017-01-08 14:10 @632

Buenas, otra vez.

Repasando otra vez el ejercicio me ha venido una duda, en el penúltimo script que me mandaste.

if ($min_skew > $diferencia_GC) {
$min_skew = $diferencia_GC; # tenemos un nuevo mínimo
@posiciones_minimo = (); # reiniciamos el almacén de posiciones
}

No logro entender lo que haces con @posiciones_minimo

Muchas gracias.
angelluigi
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2016-11-16 08:52 @411

Re: Posiciones de un array

Notapor explorer » 2017-01-08 16:57 @748

El objetivo es saber en qué posiciones encontramos el mínimo (valor más pequeño) de la diferencia entre 'C' y 'G'.

Entonces, en el if() nos preguntamos si hemos encontrado un valor más pequeño que el que tenemos hasta ahora ($min_skew). Si la $diferencia_GC es menor que $min_skew, resulta que hemos encontrado un mínimo más pequeño, así que todas las @posiciones_minimo que teníamos antes, ya no nos valen (no nos interesan), y por eso reiniciamos el array.

En la línea siguiente hay otro if(), que se cumplirá en el caso de que hayamos encontrado un mínimo más pequeño: en la línea 24 igualamos el valor de las variables, así que la condición de la línea 28 se cumple, por lo que la 29 se ejecuta siempre que encontremos un nuevo mínimo más pequeño. Y la labor de la línea 29 es almacenar la posición de ese nuevo mínimo (de ese, y de todos los demás que sigan iguales a $min_skew).
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