use Cwd;
... my $initdir = getcwd();
my $dir = '/Volumes/EQ15_SM';
chdir($dir);
...
chdir($initdir); |
On va aller faire le travail dans le répertoire cible, puis revenir au répertoire de départ une fois le travail terminé.
Manifestement, le programme R se coltine des noms complets, ce qui n'a aucun intérêt:
filepath <- file.path("/Volumes/EQ15_SM",paste(i,".txt",sep="" ))
my @flist = glob("*.txt" );
foreach my $infile (@flist) {
next unless ($infile =~/^[^.].*\.txt$/);
...
} |
On récupère avec glob la liste des fichiers en .txt du répertoire, et on va travailler un par un sur chacun (foreach...)
On saute les fichiers commençant par un . (j'ai pas testé l'expression régulière /^[^.].*\.txt$/ car windows XP n'accepte pas les fichiers commençant avec un . apparement mais elle devrait être bonne.) Si je saute ces fichiers, c'est parce que j'ai lu que la fonction R qui est utilisée le faisait
filenames<-dir("/Volumes/EQ15_SM",pattern="\\.txt" )
my $outfile = $infile =~ s/^(.*)(\.txt)$/${1}_final${2}/r; |
Je construis le nom du fichier de sortie en insérant _final dans le nom du fichier d'entrée
Le code R fait des choses qui sont un peu inutiles ou complexes, qui exploitent le fait que les fichier ont des noms de exactement 5 caractères avant l'extension:
names_files<-substr(filenames,1,5)
...
write.table(Files_fin[[i]], paste(names(Files_fin)[i], ".pc", sep = "" ),
C'est avec une extension .pc que c'est fait ici et non _final.txt
Si vous voulez un nom de fichier résultat avec .pc, il suffit de changer mon code en:
my $outfile = $infile =~ s/^(.*)(\.txt)$/${1}.pc/r;
open(my $infh, '<', $infile);
open(my $outfh, '>', $outfile);
.....
close($infh);
close($outfh); |
On ouvre en lecture le fichier d'entrée, en écriture celui de sortie, et on les ferme après traitement
while (my $line = <$infh> ) {
chomp $line;
my @cols = split(/\t/, $line);
....
} |
On lit le fichier ligne a ligne et on traite chaque ligne.
D'abord on vire le retour a la ligne final, puis on découpe la ligne comme des champs de texte séparés par des tabulations.
if ($. == 1) {
push @outcols, 0..2, grep($cols[$_] =~ /^B(B|P)/, 0..$#cols);
@cols = @cols[@outcols];
@logcols = grep($cols[$_] =~ /raw/, 0..$#cols);
$cols[0] = "Name";
$cols[1] = "Chr";
$cols[2] = "Position";
foreach (@cols) {
if (/^B(B|P)/) {
s/-//g;
s/_raw$/.Log R Ratio/ or s/_baf$/.B Allele Freq/ or s/_cn$/.cn/;
}
}
} |
Si c'est la première ligne ($. == 1), on récupère les indices des champs utiles: les 3 premiers (0..2)et ceux qui démarrent par BB ou BP (/^B(B|P)/)
On ne conserve alors que les champs utiles: @cols = @cols[@outcols];
On cherche maintenant parmi eux les indices de ceux contenant raw (c'est ceux dont on va transformer la valeur avec log2)
On remplace ensuite le texte des têtes de colonne (ie les champs de cette première ligne) par les valeurs voulues en sortie.
else {
@cols = @cols[@outcols];
foreach (@logcols) {
$cols[$_] = log($cols[$_])/log(2);
}
@cols = map {looks_like_number($_)?0+$_:$_} @cols;
} |
Si ce n'est pas la première ligne, on filtre pour ne garder que les champs attendus en sortie: @cols = @cols[@outcols];
Et pour ceux qui ont besoin du remplacement par le log de la valeur, on fait ce remplacement.
La ligne @cols = map {looks_like_number($_)?0+$_:$_} @cols; c'est pour que en sortie, Perl se comporte comme R:
Quand Perl lit un champ avec 1.48844e+07, pour lui, c'est du texte, et il va l'écrire comme il l'a lue. En effectuant une addition avec 0, Perl va dorénavant considérer le champ comme un nombre et l'écrire 14884400 en sortie (comme le fait R)
print $outfh join("\t", @cols), "\n"; |
On écrit les champs utiles et éventuellement modifiés dans le fichier de sortie.
A+,
Message édité par gilou le 17-05-2013 à 13:35:43
---------------
There's more than what can be linked! -- Iyashikei Anime Forever! -- AngularJS c'est un framework d'engulé! --