hash of hash

A

Andrea Spitaleri

Hi everyone,
I am a bit stuck with a script.
Here is the problem:
I have a script wich creates an output like that:

aa1 0.1 0.2 0.55
aa2 -0.4 0.3 -0.4
aa3 0.04 -0.4 0.1
...........
and I would like to "invert" it in:
aa1 aa2 aa3
1 0.1 -0.4 0.04
2 0.2 0.3 -0.4
3 0.55 -0.4 0.1

any idea? I don't post the script because it is quite long.

thanks
regards

xspirix
 
G

Gunnar Hjalmarsson

Andrea said:
I am a bit stuck with a script.
Here is the problem:
I have a script wich creates an output like that:

aa1 0.1 0.2 0.55
aa2 -0.4 0.3 -0.4
aa3 0.04 -0.4 0.1
..........
and I would like to "invert" it in:
aa1 aa2 aa3
1 0.1 -0.4 0.04
2 0.2 0.3 -0.4
3 0.55 -0.4 0.1

any idea? I don't post the script because it is quite long.

Then write and post a *small* script that illustrates the problem and
shows the best attempt you have made so far.
 
A

Anno Siegel

Please use a subject that has something to do with your question.
There's no hash of hashes in what you ask.
Hi everyone,
I am a bit stuck with a script.
Here is the problem:
I have a script wich creates an output like that:

aa1 0.1 0.2 0.55
aa2 -0.4 0.3 -0.4
aa3 0.04 -0.4 0.1
..........
and I would like to "invert" it in:
aa1 aa2 aa3
1 0.1 -0.4 0.04
2 0.2 0.3 -0.4
3 0.55 -0.4 0.1

So what you want to do is transpose the lines of the first table so
that they become the columns of the second one. Also, you want to
add numbering to the transposed lines. You could have put a little
more effort into explaining this, instead of dropping us an example
and mumbling something about "invert".
any idea? I don't post the script because it is quite long.

In other words, you haven't tried anything yet. What your script
does to arrive at the original output is irrelevant.

If you have the original lines in @lines, you can do this to get the
columns:

my @cols;
push @cols, [ $_, map shift( @$_), @lines] for '', 1 .. 3;

Anno
 
A

Arndt Jonasson

I am a bit stuck with a script.
Here is the problem:
I have a script wich creates an output like that:

aa1 0.1 0.2 0.55
aa2 -0.4 0.3 -0.4
aa3 0.04 -0.4 0.1
..........
and I would like to "invert" it in:
aa1 aa2 aa3
1 0.1 -0.4 0.04
2 0.2 0.3 -0.4
3 0.55 -0.4 0.1

"Hash of hash" seems to have very little to do with this problem.
"List of lists" is a little closer, and there are tutorials on
that subject in the supplied documentation.

Also, the word you want may be "transpose", not "invert", at least if
there is a mathematician within hearing distance. (In the database
world, "invert" probably has a meaning distinct from the mathematical
one.)

The program below may be doing something similar to what you want. It
first splits the lines and produces an array of references to arrays
of strings (@table1). It then iterates over all the elements, line by
line, and creates another array of references to arrays of strings
(@table2), and finally prints out @table2 (without line numbers - they
can be added easily).

(I think @lines in Anno's solution corresponds to my @table1, rather
than my @lines.)

It doesn't depend on knowing the dimensions of the table, nor, as as
far I can see, on the table's being rectangular.

I would have liked to get rid of the $j variable. It's probably possible.


#! /usr/bin/perl -w

#use strict;
use diagnostics;

my @lines = <DATA>;
my @table1 = map {my @l = split /\s+/, $_; \@l} @lines;

my @table2;

foreach my $lr (@table1) {
my $j = 0;
push @{$table2[$j++]}, $_ foreach @$lr;
}

foreach my $lr (@table2) {
print " $_" foreach @$lr;
print "\n";
}
__DATA__
aa1 0.1 0.2 0.55
aa2 -0.4 0.3 -0.4
aa3 0.04 -0.4 0.1
 
A

andrea spitaleri

Hi,
I tried many different ways to resolve it, even if I am still a newbie
in perl. Don't be cruel :) It is not my intention to waste my and your time.
The problem is a bit more complicated. I have a datafile like that:
ala21,-0.03
thr43,0.06
phe124, 0.01
......
sorted for the number of the first column (21<43), and then I have a
series of files from which I need to parse some data, which are "linked"
to the first column of the datafile. The problem is that in those files
the sequence of the data is unsorted:
first file:
560 <other numbers> -0.04
54 ................. 0.02
235 ................ 0.01
..............
second file:
560 <other numbers> -0.01
54 ................. 0.05
235 ................ 0.03
third file:
560 <other numbers> -0.08
54 ................. 0.1
235 ................ 0.11
and so on.
basicaly:
aa num shift_1 shift_2 shift_3 ....
ala21 -> 54 -> 0.02 0.05 0.1
and so on.
The only way to do it (for me..) is to make an hash between the first
value of the datafile (ala21) with the smallest value of the files, the
second value (thr43) with the second smallest value of the files, and so on.
for doing this I need first of all sort by the key of the second hash
obtained from the files, and then link to datafile
have a look to my script:
#!/usr/bin/perl

use warnings;
use strict;

die "USAGE : $0 shiftfile number\n" if ($#ARGV!=1);
my (@tmp1,@tmp,@aa,@cis,%NEW);
my ($num,$shift,$i);
my $count=0;
open (SFT,"$ARGV[0]") or die "$!";
open (OUT,">tmp.csv") or die "$!";

while (my $line=<SFT>){
chomp $line;
@tmp=split(/,/,$line);
chop $tmp[1];
push @aa,$tmp[0];
push @cis,$tmp[1];
}

foreach my $file (1 .. $ARGV[1]){
open (IN,"rank_$file\.sft") or die "$!";
print "rank_$file\.sft\n";
while(my $lines=<IN>){
chomp $lines;
if($lines=~ /^ Atom number expt ring sp2anis
Efield total/){
$i=0;
while(my $nlines=<IN>){
chomp $nlines;
@tmp1=split(/ +/,$nlines);
$num=$tmp1[1];
$shift=$tmp1[11];
push (@{$NEW{$num}}, $shift);
++$i;
}
}
}
++$count;
}

my $j=0;
foreach my $index (sort {$a<=>$b} keys %NEW){
# print OUT "@{$NEW{$index}} $sft[$j]";
print OUT "$aa[$j] $cis[$j] @{$NEW{$index}}\n";
++$j;
}
print "$i cis and $count files done\n";
print "tmp.csv created. Open it with OOo using space and comma as
separator\n";

That works quite well for giving my what I want. The problem is then if
I want to "transpose" (thanks Arndt) the matrix obtained from that script.
A good idea was to make:
push (@{$TMP{$file}}, $shift};
but the $shift are not linked to the $num, so I cannot link with the
data from datafile anymore.
That why I said hash of hash (or maybe I am still wrong?)
I will try to use your suggestions in the script above.

thanks

regards

xspirix
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,163
Messages
2,570,897
Members
47,434
Latest member
TobiasLoan

Latest Threads

Top