1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| #!/usr/bin/perl
#!/usr/local/bin/perl -w
############################################################################################
#
#
# Script pour créer une matrice de genotypage realisant la synthèse de 2 matrices différentes
#
# usage: perl ./ trois fichier (a renommer avant le lancement du script
# -fic1.txt (premiere matrice de données)
# -fic2.txt (deuxieme matrice de données)
# -fic3.txt (troisieme matrice genere le resultat voulu)
#
# en sortie: une matrice de synthèse
#
# creation: 08/03/2012- Cyril Plantard
#
############################################################################################
use strict;
use warnings;
use feature qw(:5.10);
use List::MoreUtils qw(each_array);
sub merge_cols(\@\@$) {
foreach my $invalid (grep $_ eq "XX", values %$columns) {
warn "Different homo/homo or hetero/hetero at line $. in\n$line\n";
$invalid = "--";
}
my ($col_names, $col_values, $columns) = @_;
my $col_index = 0;
foreach my $col_value (@$col_values) {
my $col_name = $col_names->[$col_index++];
if (!exists $columns->{$col_name}) {
# ajoute une nouvelle colonne
$columns->{$col_name} = $col_value;
}
else {
my $existing_col = $columns->{$col_name};
if ($existing_col eq "--" || $col_value eq "--") {
my $value = $existing_col eq "--" ? $col_value : $existing_col;
# Choisissez le courant col si présentent déjà à la ligne actuelle
$columns->{$col_name} = (grep $_ eq $value, values %{$columns}) ? $col_value : "--";
}
else {
# selectionne le dominant
my %cur_char = map { $_ => 1 } split //, $existing_col;
my %new_char = map { $_ => 1 } split //, $col_value;
my $char_cmp = keys %cur_char <=> keys %new_char;
$columns->{$col_name} = $char_cmp < 0 ? $existing_col : $char_cmp > 0 ? $col_value :
$existing_col eq $col_value ? $col_value : "XX";
}
}
}
}
sub load_table {
my ($result_tabref, $result_keyref, $file) = @_;
open my $TABLE, "<", $file or die "Can't open $file: $!";
chomp(my $line = <$TABLE>);
my ($test_key, @col_names) = split /\s+/, $line;
if (!@$result_tabref) {
# Créez la première rangée contenant une clé de test et un hash de noms de colonne
my $column_number = 1;
push @$result_tabref, [ $test_key, { map { $_ => $column_number++ } @col_names } ];
}
else {
# complete la premiere colonne
my $columns = $result_tabref->[0]->[1];
my $column_number = 1 + keys %$columns;
$columns->{$_} = $column_number++ foreach grep !exists $columns->{$_}, @col_names;
}
#my $col_number = keys %{$result_tabref->[0]->[1]};
while (defined($line = <$TABLE>)) {
chomp $line;
my ($test_key, @col_values) = split /\s+/, $line;
if (exists $result_keyref->{$test_key}) {
# Compléte une rangée existante
my $columns = $result_tabref->[$result_keyref->{$test_key}]->[1];
my $col_index = 0;
merge_cols(@col_names, @col_values, $columns);
}
else {
# Créez une liste de valeurs de colonne manquantes (du numéro de colonne de la première rangée)
my $col_index = 0;
push @$result_tabref, [ $test_key, { map { $col_names[$col_index++] => $_ } @col_values } ];
$result_keyref->{$test_key} = $#$result_tabref;
}
}
}
sub print_table {
my ($tabref, $file) = @_;
open my $OUT, ">", $file or die "Can't open $file: $!";
# la rangée contient des noms de colonne et les positions
my ($first_col, $col_names) = @{shift @$tabref};
my @col_names = sort { $col_names->{$a} cmp $col_names->{$b} } keys %$col_names;
say { $OUT } join " ", $first_col, @col_names;
foreach my $row (@$tabref) {
# la rangée contient des noms de colonne et les positions
my ($test_key, $col_values) = @$row;
say { $OUT } join " ", $test_key, map $col_values->{$_} // "--", @col_names;
}
}
# telechargement des deux fichiers fic1.txt et fic2.txt
my (@table, %test_keys);
load_table(\@table, \%test_keys, "fic1.txt");
load_table(\@table, \%test_keys, "fic2.txt");
# ecriture du fichier final fic3.txt
print_table(\@table, "fic3.txt"); |