Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Query of multi dimentional array

by shabird (Sexton)
on Mar 26, 2020 at 09:51 UTC ( [id://11114659]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks, hope you all are fine

I am struggling with multi dimensional array this time so basically the question goes like this, I have a file which has a data like this

GeneID Tp1 Tp2 Tp3 ALA1 10 12 11 THR8 57 99 12 HUA4 100 177 199 ABA5 2 5 10

So i have read the file and assigned it to multi dimensional array with the help of this code.

my @content = (<FH>); close(FH); my $no_of_seq = scalar(@content); my @myArray; foreach my $row (@content) { my @columns = split(/\s+/,$row); push(@myArray,\@columns); # print "@columns"; } for($row = 0; $row < $no_of_seq; $row++){ for($col = 0; $col < $no_of_seq; $col++){ print($myArray[$row][$col], "\t"); } print("\n"); }

so this code prints every element in the same order but now i want to calculate the sum of numbers in each row and print that sum next to gene name i.e sum of values for ALA1 is 33 and sum of values for THR8 is 168 and so on. Now i have tried something like this.

for($row = 0; $row < $no_of_seq; $row++){ for($col = 0; $col < $no_of_seq; $col++){ $sum = $myArray[$row][$col] + $myArray[$row]; print($sum, "\t"); }

But this is printing something like this

140526414289424 140526414289424 140526414289424 1405264142894 +24 140526414289424 140526414212840 140526414212850 140526414212852 1405264142128 +51 140526414212840 140526414213296 140526414213353 140526414213395 1405264142133 +08 140526414213296 140526414288368 140526414288468 140526414288545 1405264142885 +67 140526414288368 140526414313944 140526414313946 140526414313949 1405264143139 +54 140526414313944

How can i achieve my desired result? thank you in advance

Replies are listed 'Best First'.
Re: Query of multi dimentional array
by choroba (Cardinal) on Mar 26, 2020 at 10:09 UTC
    $myArray[$row] is a reference to an array, you seem to be adding it to the actual numbers in the columns. That's why the values are so high. You can simplify the algorithm by iterating over the values rather than indices:
    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; my @content = (<DATA>); my $no_of_seq = scalar(@content); my @myArray; for my $row (@content) { my @columns = split ' ', $row; push @myArray, \@columns; } say join "\t", $myArray[0][0], 'sum'; my $width = $#{ $myArray[0] }; for (my $row = 1; $row < $no_of_seq; $row++){ print $myArray[$row][0], "\t"; my $sum = 0; for my $col (@{ $myArray[$row] }[1 .. $width]) { $sum += $col; } say $sum; } __DATA__ GeneID Tp1 Tp2 Tp3 ALA1 10 12 11 THR8 57 99 12 HUA4 100 177 199 ABA5 2 5 10

    Update: But, to compute a sum of a row, you don't need the other rows, so you can process the file line by line, no need to store it into an array. List::Util already exports the sum sub, no need to compute it yourself.

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use List::Util qw{ sum }; <DATA>; # ignore the first line; say "GeneID\tSum"; while (<DATA>) { my @cols = split ' '; my $sum = sum(@cols[1 .. $#cols]); say join "\t", $cols[0], $sum; }

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      And just in case you wanted to search by GeneID (which is very likely in a next step):

      my %myArray; #my @myArray; my $GeneID = shift @columns; $myArray{$GeneID} = \@columns; #push @myA +rray, \@columns; # and how to calculate sum of each row for my $GeneID (sort keys %myArray){ # optionally sort to have a consi +stent view my $sum = 0; for my $colItem (@{$myArray{$GeneID}}){ $sum += $colItem; } print "sum for $GeneID: $sum\n"; }

      bw, bliako

Re: Query of multi dimentional array
by marto (Cardinal) on Mar 26, 2020 at 09:58 UTC

    It seems from your post history that you are interested in bioinformatics, in case you are not aware BioPerl exists, and provides various solutions to common tasks, in addition to other things.

    Update: Also Tutorials->Perl and Bioinformatics.

      Hi marto i know about BioPerl but i don't want to use that i just want to do it the manual way the way i am doing it.

Re: Query of multi dimensional array
by hippo (Bishop) on Mar 26, 2020 at 10:24 UTC

    You will need to keep a count of the total per row, but you are not doing so yet. Further your code is trying to add a single value to an array which logically makes no sense. Also, each row contains the gene name as well as the data so you need to avoid trying to add a number to a string.

    Using your loop structures then we might try this instead:

    for($row = 0; $row < $no_of_seq; $row++){ my $sum = 0; for($col = 1; $col < $no_of_seq; $col++){ $sum += $myArray[$row][$col]; } print "$myArray[$row][0] $sum\n"; }

    But that's not very perlish. Let's improve the loops:

    for my $row (@myArray) { my $sum = 0; for ($col = 1 .. $no_of_seq - 1) { $sum += $row[$col]; } print "$row[0] $sum\n"; }

    This could be further cleaned if you work on a copy of @myArray which you could disrupt as you go. Putting this all together we arrive at the SSCCE:

    #!/usr/bin/env perl use strict; use warnings; my @myArray; while (<DATA>) { my @columns = split /\s+/, $_; push @myArray, \@columns; } my $title_row = shift @myArray; for my $row (@myArray) { my $sum = 0; for my $col (1 .. $#$row) { $sum += $row->[$col]; } print "$row->[0] $sum\n"; } __DATA__ GeneID Tp1 Tp2 Tp3 ALA1 10 12 11 THR8 57 99 12 HUA4 100 177 199 ABA5 2 5 10
      Unfortunately your solution isn't printing anything to the terminal :(

        Sure it does:

        $ cat bio.pl #!/usr/bin/env perl use strict; use warnings; my @myArray; while (<DATA>) { my @columns = split /\s+/, $_; push @myArray, \@columns; } my $title_row = shift @myArray; for my $row (@myArray) { my $sum = 0; for my $col (1 .. $#$row) { $sum += $row->[$col]; } print "$row->[0] $sum\n"; } __DATA__ GeneID Tp1 Tp2 Tp3 ALA1 10 12 11 THR8 57 99 12 HUA4 100 177 199 ABA5 2 5 10 $ ./bio.pl ALA1 33 THR8 168 HUA4 476 ABA5 17 $ perl -v This is perl 5, version 20, subversion 3 (v5.20.3) built for x86_64-li +nux-thread-multi (with 16 registered patches, see perl -V for more detail) Copyright 1987-2015, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge. $
Re: Query of multi dimentional array
by kcott (Archbishop) on Mar 27, 2020 at 02:01 UTC

    G'day shabird,

    "How can i achieve my desired result?"

    You could try the sum0 function from the core List::Util module.

    This code:

    #!/usr/bin/env perl use strict; use warnings; use List::Util 'sum0'; my (@all_data, @sum_data); while (<DATA>) { next if $. == 1; push @all_data, [split]; } print "All (original) data:\n"; print "@$_\n" for @all_data; for (@all_data) { push @sum_data, [$_->[0], sum0 @$_[1 .. $#$_]]; } print "\nSummary data:\n"; print "@$_\n" for @sum_data; __DATA__ GeneID Tp1 Tp2 Tp3 ALA1 10 12 11 THR8 57 99 12 HUA4 100 177 199 ABA5 2 5 10

    Produces this output:

    All (original) data: ALA1 10 12 11 THR8 57 99 12 HUA4 100 177 199 ABA5 2 5 10 Summary data: ALA1 33 THR8 168 HUA4 476 ABA5 17

    — Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11114659]
Approved by marto
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (9)
As of 2024-04-26 08:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found