> Good morning, Zeus.

Good morning.
 
> Your codes is so neat and clean.  I appreciate your help. 

Why thank you. Everyone loves compliments.
:-)

> I have one question to you though. 

You are more than welcome to cc me via email. However, please post to
perl.beginners in case I am away from my email and can't answer your query
in a reasonable timeframe.

> In the sub routine count, 
> you used shift function.  Does the shift function go through 
> all the elements in a array?

Any time you don't understand a Perl function, look it up via perldoc. You
should NEVER ask a question about built-in functions without reading about
them first, ala:

  $ perldoc -f shift

You should probably read 

  $ perldoc perldoc 

also.

Therefore, the shift() in the sub:

  sub count {
    my $search = shift;
    return scalar grep { $_ eq $search } @_;
  }

Removes the first element of an array and stores it in $search. Because I
did not specify which array, the default array for subs is @_. If I had been
outside of a subroutine, the default array is @ARGV.

The first call to count is 

  my $m = count('M', @treat);

where @treat = ('P', 'P', 'P', 'P'). Because arguments are flattened by Perl
into one array the actual call that gets executed is:

  my $m = count('M', 'P', 'P', 'P', 'P');

When the code enters the subroutine, @_ is aliased to ('M', 'P', 'P', 'P',
'P'). Therefore, the line

  my $search = shift;

sets $search = 'M' and concurrently changes @_ to ('P', 'P', 'P', 'P'). Look
familiar? It should because this is Treatment 1 from the first record of
your data. The next line 

  return scalar grep { $_ eq $search } @_;
 
does what you initially asked and goes "through all the elements in a array"
via the grep function.

  $ perldoc -f grep

Each time grep encounters M it returns that element. In this particular case
there are no M's and thus grep returns an empty list. The "return scalar"
says interpret the expression in scalar context. Since we have an empty
list, this evaluates to 0 (zero). return says go back to the calling routine
and take back the result to the right (0). Yep, you guessed it:

  $ perldoc perlsub
  $ perldoc -f scalar
  $ perldoc -f return

perldoc is your FRIEND!

> If the data starts with a 'A' instead of 'P' or 'M', the 
> number of 'P' or 'M' in that line will be counted or not? 

This should now be clear: The first arugment to count() is the search
string. count() then searches for the search string in the rest of the
arugments. If the search string is found, count() returns the number of
occurrences, zero otherwise.

If you are a true Perl beginner, read an intro book first. I hear that
_Learning Perl_ by Randal L. Schwartz and Tom Phoenix is excellent.
http://www.bestwebbuys.com/Learning_Perl-ISBN_0596001320.html?isrc=b-search.
You should get the two Perl bibles: _Programming Perl 3rd Ed_ by Larry Wall
and _Perl Cookbook_ by by Tom Christiansen and Nathan Torkington.

> I 
> hope that I made myself clear to you now.  

Crystal clear. I hope I have done the same.
 
> Thanks a lot!

You're welcome. Good luck.
-ZO
 
> -----Original Message-----
> From: Zeus Odin [mailto:[EMAIL PROTECTED]
> Sent: Friday, November 12, 2004 12:09 AM
> To: Li, Aiguo (NIH/NCI)
> Subject: Re: Why doesn't this work?
> 
> 
> 
> "Aiguo Li" <[EMAIL PROTECTED]> wrote in message ...
> 
> > Probe id Treat1 Treat2
> > AffX-BioB-5_at (2p +M)/4 =2 (2*3+0)/3=2
> > FFX-BioB-M_at (2*3+0)/4 =1.7 (2*3+0)/3=2
> > AFFX-BioB-3_at (2*2+0)/4 =1 (2*2+0)/3=1.3
> > AFFX-BioC-5_at (2*2+1)/4 =1.25 (2*1+1)/3=1
> > AFFX-BioC-3_at (2*1+1)/4 = 0.75 (2*2+1)/3=1.7
> >
> > The denominator is always the # of replicates in each treatment.
> 
> Excellent. This is *much* clearer. The following appears to 
> do what you
> want. See comments about your code below.
> 
> ---------------
> #!/usr/bin/perl
> use warnings;
> use strict;
> 
> while (<DATA>) {
>   next unless /^A/;
>   my @data = split;
> 
>   print join("\t", $data[0], PA(@data[1..4]), 
> PA(@data[5..7])), "\n"; }
> 
> sub PA {
>   my @treat = @_;
>   my $m = count('M', @treat);
>   my $p = count('P', @treat);
>   return (2*$p + $m) / @treat;
> }
> 
> sub count {
>   my $search = shift;
>   return scalar grep { $_ eq $search } @_;
> }
> 
> __DATA__
> Replicates      1 1 1 1 2 2 2
> AFFX-BioB-5_at  P P P P P P P
> AFFX-BioB-M_at  P P P P P P P
> [snip]



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to