• Publicidad

Comparar columnas de dos archivos muy pesados

Perl aplicado a la bioinformática

Comparar columnas de dos archivos muy pesados

Notapor K-lixto » 2011-08-16 11:15 @510

Hola, he visto otros temas relacionados y los he revisado con detenimiento pero no logro usar estos antecedentes para resolver mi problema:

Tengo un archivo (tabulado) de varios gigabytes y otro no tan grande. Quiero comparar "string" que están en las columnas 2 de cada uno de ellos, y si es positivo, imprimir las columnas 1,2,3 del archivo primero y las columnas 1,2,3 del archivo segundo.

Dejo el código que tengo desarrollado para ver si me ayudan en su elaboración.
Gracias de antemano.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! /usr/bin/env perl
  2. use warnings;
  3. use strict;
  4. my %hash;
  5. my @arr1;
  6. my @arr;
  7. my $uniprot;
  8. my $arr;
  9. my @allhit;
  10.  
  11. open( FH,     "<archivo1.txt" );
  12. open( OUTPUT, ">Annot_cDNA_Uniprot_GOA.txt" );
  13. while (<FH>) {
  14.     my @arr = split( "\t", $_ );
  15.     $hash{GOA} = $arr[1];
  16.  
  17.     #print $hash{GOA};
  18. }
  19. close(FH);
  20.  
  21. open( FH1, "<archivo2.txt" );
  22. while (<FH1>) {
  23.     my @arr = split( "\t", $_ );
  24.     $uniprot = $arr[1];
  25.     if ( exists( $hash{GOA} ) ) {
  26.         push( @allhit, $arr[1], $arr[3], $arr[7] );
  27.  
  28.         #my $allhit = join("\t", $hash{GOA}[1], @arr);
  29.         print OUTPUT @allhit;
  30.     }
  31.     else { next; }
  32. }
  33. close(FH1);
Coloreado en 0.006 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2011-08-16 11:45 @531, editado 1 vez en total
Razón: Formateado de código con Perltidy y poner marcas Perl
K-lixto
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2011-05-13 14:46 @657

Publicidad

Re: Comparar columnas de dos archivos muy pesados

Notapor explorer » 2011-08-16 11:48 @533

¿Dispones de suficiente memoria como para guardar la información del fichero más pequeño en un estructura hash?

P.D. Juraría que el código no funciona, sin importar el tamaño de los ficheros.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comparar columnas de dos archivos muy pesados

Notapor K-lixto » 2011-08-16 12:27 @560

Demora mucho por lo que la memoria no sé si será limitante, son 2Gb de RAM. Y ciertamente no me está funcionando.
K-lixto
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2011-05-13 14:46 @657

Re: Comparar columnas de dos archivos muy pesados

Notapor explorer » 2011-08-16 12:55 @580

A ver, lo que he preguntado es si la información del fichero más pequeño cabe en la memoria del ordenador.

Es decir. Tienes que mirar a ver si este programa se ejecuta de forma correcta:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use 5.010;
  3. use autodie;
  4.  
  5. my %archivo2;
  6. my $n_lineas;
  7.  
  8. open my $ARCHIVO2, q[<], 'archivo2.txt';
  9.  
  10. while (<$ARCHIVO2>) {
  11.     chomp;
  12.     my @campos = split;                             # suponemos que los campos están separados por espacios
  13. #    next if @campos < 3;                            # seguimos con la siguiente línea si hay menos de 3 campos
  14.     $archivo2{$campos[1]} = [ @campos[ 0 .. 2 ] ];
  15.     $n_lineas++;
  16. }
  17.  
  18. close $ARCHIVO2;
  19.  
  20. say "Número de líneas leídas: $n_lineas. Número de claves leídas: ", scalar keys %archivo2;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Dices que tienes 2Gb de memoria RAM, pero no nos has dicho cuánto ocupa el fichero más pequeño, ni en qué sistema operativo estás.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comparar columnas de dos archivos muy pesados

Notapor K-lixto » 2011-08-16 13:19 @596

El archivo más chico contiene 800 kb, el mayor 15 Gb, el cual intento poner dentro de un hash. Trabajo con MACosx.

El archivo de 800 kb es la salida de un blast, formato tabla. El segundo archivo es una tabla de una base de datos de clasificación de proteínas. Intento poder extraer los identificadores de la salida del blast que están en la base de datos (segundo archivo), agregando al archivo de salida algunas columnas del archivo primero (digamos columnas 1,2 y 3) y algunas columnas del segundo archivo (bases de datos).
K-lixto
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2011-05-13 14:46 @657

Re: Comparar columnas de dos archivos muy pesados

Notapor explorer » 2011-08-16 15:59 @708

No nos dices si has ejecutado mi programa o no, pero siendo 800Kb, yo creo que no habrá problemas. Tampoco sabemos si los campos número 2 pueden aparecer más de una vez en el fichero. Pero en fin, quizás se pueda resolver de forma inversa, es decir: leer el fichero blast en memoria, y luego ir leyendo la base de datos.

No lo he probado, pero debería ser algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use autodie;
  3.      
  4. my %blast;
  5. my $n_lineas;
  6.      
  7. open my $BLAST, q[<], 'blast.txt';
  8. while (<$BLAST>) {
  9.     chomp;
  10.     my @campos = split;                             # suponemos que los campos están separados por espacios
  11.     #next if @campos < 3;                            # seguimos con la siguiente línea si hay menos de 3 campos
  12.     push @{ $blast{$campos[1]} } , @campos[ 0, 1, 3 .. 5 ];
  13.     $n_lineas++;
  14. }
  15. close $BLAST;
  16.      
  17. print "BLAST: Número de líneas leídas: $n_lineas. Número de claves leídas: ", scalar(keys %blast), "\n";
  18.  
  19. $n_lineas = 0;
  20. open my $DB, q[<], 'base_datos.txt';
  21. while (<$DB>) {
  22.     chomp;
  23.     my @campos = split;                             # suponemos que los campos están separados por espacios
  24.     #next if @campos < 3;                            # seguimos con la siguiente línea si hay menos de 3 campos
  25.  
  26.     if (exists $blast{ $campos[1] } ) {             # ¿Tenemos información del blast en la base de datos?
  27.         push @{$blast{ $campos[1] }}, @campos[ 2 .. 3 ];
  28.         $n_lineas++;
  29.     }
  30. }
  31. close $DB;
  32.  
  33. print "Encontradas $n_lineas líneas en la base de datos.\n";
  34.  
  35. open my $SALIDA, q[>], 'Annot_cDNA_Uniprot_GOA.txt';
  36. for my $valor (values %blast) {
  37.     print $SALIDA join("\t", @{$valor}), "\n";
  38. }
  39. close $SALIDA;
  40.  
Coloreado en 0.002 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: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comparar columnas de dos archivos muy pesados

Notapor K-lixto » 2011-08-16 17:48 @783

Gracias explorer y disculpa la demora. No pude correr el código para probar la capacidad de mi computador y es que no tengo la versión 10.5 de Perl, debería instalarla.

Estoy corriendo ahora el último código, con modificaciones por lo de la versión antigua que tengo, se demora en dar la salida.

Dejaré una línea tipo de la salida del blast:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
118150550 A0JPF5 CA063227 gi|118150550 81.89   127     23      0
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y una línea tipo del archivo de la base de datos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
UniProtKB A0JPF5  moeD5  GO:0005524
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y mi necesidad es detectar si la segunda columna del primer archivo está en la segunda del segundo (en este caso coinciden con "A0JPF5") y luego generar una salida que incluya parte de ambos archivos, como por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
118150550 A0JPF5 gi|118150550 81.89   127 moeD5  GO:0005524...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
K-lixto
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2011-05-13 14:46 @657

Re: Comparar columnas de dos archivos muy pesados

Notapor explorer » 2011-08-16 18:56 @830

Ya está modificado el programa para que funcione con versiones Perl de hace cinco años :)

Y también están ajustados los campos que quieres guardar.

Una forma de saber por dónde va es modificar la línea 28, para que nos pinte por qué línea va procesando, cada diez mil líneas, por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         print "$n_lineas líneas...\n" if not $n_lineas++ % 10_000;
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: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comparar columnas de dos archivos muy pesados

Notapor salva » 2011-08-17 03:22 @182

K-lixto escribiste:Tengo un archivo (tabulado) de varios gigabytes y otro no tan grande. Quiero comparar "string" que están en las columnas 2 de cada uno de ellos, y si es positivo, imprimir las columnas 1,2,3 del archivo primero y las columnas 1,2,3 del archivo segundo.


Como te comenta explorer, si tienes memoria suficiente para leer el archivo pequeño en un hash, esa es la solución más fácil y rápida.

Si no, la solución clásica a este problema es ordenar los dos ficheros en disco por el campo clave (usando la utilidad sort o el módulo Sort::External, por ejemplo) para luego leer los dos ficheros ordenados en paralelo buscando coincidencias.
Avatar de Usuario
salva
Perlero nuevo
Perlero nuevo
 
Mensajes: 200
Registrado: 2008-01-03 15:19 @680


Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron