koleti has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I have file that contains two columns id1 and id2 as shown below

id1    id2
208    10000
207    10000
8517   1147
3551   1147
Now i want to convert it into an adjacency matrix
as shown below
        10000     1147
208       1         0
207       1         0
8517      0         1
3551      0         1

what i want to do is give 1 if id1 and id2 are there 
else i want to give a 0
Thanks
  • Comment on how to convert two lists into adjacency matrix

Replies are listed 'Best First'.
Re: how to convert two lists into adjacency matrix
by kennethk (Abbot) on Apr 13, 2009 at 22:02 UTC
    As has been suggested before, please read Writeup Formatting Tips. In particular, you should be using <code> tags to preserve whitespace and <p> to break paragraphs.

    This is a fairly straightforward task using hashes. First iterate over your first list and increment the value on that key, i.e.

    my %hash = (); foreach my $element (@list1) { $hash{$element}++; }

    Repeat for the second list, and voila, if a key has a value of 2, it's in both lists. Post some code, and then we can help you debug it.

    Update: Or if you don't want to write any code, you could always use List::Compare::Functional.

      I think you misread the O.P. This isn't about comparing lists, and your code snippet can't get there.

      Maybe this will do:

      use strict; use warnings; my @id1 = (1..5); my @id2 = (11..15); my %hash; my %col_header; my %row_header; my $last = $#id1 > $#id2 ? $#id1 : $#id2; for my $i (0..$last) { if ( defined( $id2[$i] ) ) { $col_header{$id2[$i]} = 1; } if ( defined( $id1[$i] ) ) { $row_header{$id1[$i]} = 1; } if ( defined( $id1[$i] ) and defined( $id2[$i] ) ) { $hash{$id1[$i]}{$id2[$i]} = 1; } } my @col_header = sort numeric keys %col_header; my @row_header = sort numeric keys %row_header; printf "%10s" x (@col_header + 1), "id1\\id2", @col_header; print "\n"; for my $row ( @row_header ) { printf "%10s", "$row"; for my $col ( @col_header ) { printf "%10s", ( exists( $hash{$row}{$col} ) ? "1" : "0"); } print "\n"; } sub numeric { $a <=> $b; }

      with output:

      id1\id2 11 12 13 14 15 1 1 0 0 0 0 2 0 1 0 0 0 3 0 0 1 0 0 4 0 0 0 1 0 5 0 0 0 0 1

      (I'll leave it to OMAR to turn this into a sub.)

      Update: here's the read-from-STDIN version:

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        Hi QM, Your code has bee very helpful. Afters days of searching I now finally found this post/site and has given me faith I can do what I need (only a Perl beginner/hacker) Wondering if you could please help me do somthing like this.. which counts and is additive on multiple line items.
        id1 id2 int 208 10000 1 208 10000 7 207 10000 3 8517 1147 1 3551 1147 2 id1\id2 1147 10000 207 0 3 208 0 8 3551 1 0 8517 1 2
        I will be forever in your gratitude!
        Hi QM, Your code has bee very helpful. Afters days of searching I now finally found this post/site and has given me faith I can do what I need (only a Perl beginner/hacker) Wondering if you could please help me do somthing like this.. which counts and is additive on multiple line items. id1 id2 int 208 10000 1 208 10000 7 207 10000 3 8517 1147 1 3551 1147 2 id1\id2 1147 10000 207 0 3 208 0 8 3551 1 0 8517 1 2 I will be forever in your gratitude!
Re: how to convert two lists into adjacency matrix
by linuxer (Curate) on Apr 13, 2009 at 21:59 UTC

    Please have a look at How do I compose an effective node title? and at Markup in the Monastery.

    Don't misuse <pre>-Tags here.

    To your question: you're telling what you have as data source and what the desired result should look like.

    But you don't show where you have your problems...

    So, where's your problem hidden? What do you have problems with?

    Are you looking for someone to write your code?

    Update: You could do something like this (if you want to do it on your own):

    • read data
      • read data file and ignore header line
      • chomp and split each line into two pieces
      • create an entry in a hash-of-hash (HoH); $hash{id1}->{id2} = 1;
      • store id2 in an array if not already in that array
    • output:
      • for each key in %hash print that key; check for every entry in your array if an entry in the HoH exists, if so, print 1, if not, print 0.
Re: how to convert two lists into adjacency matrix
by metaperl (Curate) on Nov 06, 2009 at 14:33 UTC
    How do you plan to use/access your generated adjacency matrix?

    By adjacency matrix, I assume you mean something like what is mentioned in this article?

    In that article, there is no explicit listing of the values in the adjacency matrix.