http://qs321.pair.com?node_id=475438

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

Hi monks,

I'm having a lil problem here.
For example, theres this sequence here..
$sequence = 1234567890;
For arrays right, the number "1" will be in position 0, "2" will be in position 1 and so on..
So, as you can see I'm going to make it to reading frames so it'll be like this.

First reading frame: 1234567890
Second reading frame: 234567890
Third reading frame: 34567890

How do i make it to second reading frame by using an array? i can only display it using substring:
$frame2 = substr($sequence, 1);
which is wrong as the "2" in "234567890" will still be in position 1.. instead of 0 (which is what i want).So basically, i want the second reading frame in an array with the number "2" in position 0. And for the third reading frame, the number "3" also in position 0. How is that possible?

Thanks!

Replies are listed 'Best First'.
Re: Array - Reading frame problem
by GrandFather (Saint) on Jul 16, 2005 at 13:24 UTC

    Do you mean that you want the string to do this:

    0123456789 123456789 23456789 3456789 456789 56789 6789 789 89 9

    Perl is Huffman encoded by design.

      yes.. kind of.. but i was wondering if it is possible to have "individual" codes which can be reused to find $frame2 and $frame3 respectively (but there's only a need to change variable names).. and not in not in a while loop? it's because i only need to obtain another two more reading frames.


      eg.
      $sequence = "1234567890";
      $sequence .= $frame1;
      $frame 2 = "234567890";
      $frame 3 = "34567890";

        Why are you now using strings in your example, I though the whole point was you wanted to do this on an array (although there is a perf hit, split/join can let you switch back and forth....). String operations are going to be a lot faster here than array operations if you doing this alot with long sequences...

        Isn't this just what you want?

        my @frame1 = @sequence; my @frame2 = @sequence; my @frame3 = @sequence; shift @frame2; shift @frame3; shift @frame3;
Re: Array - Reading frame problem
by jdporter (Paladin) on Jul 16, 2005 at 20:22 UTC

    I've written a module to solve your problem directly; it uses tied strings. See Tie::Scalar::Substring.

    In your case, you could use it like this:

    $sequence = 1234567890; my( $frame1, $frame2, $frame3 ); tie $frame1, 'Tie::Scalar::Substring', \$sequence, 0; tie $frame2, 'Tie::Scalar::Substring', \$sequence, 1; tie $frame3, 'Tie::Scalar::Substring', \$sequence, 2;
Re: Array - Reading frame problem
by trammell (Priest) on Jul 16, 2005 at 15:59 UTC
    Hard to say exactly what it is you want (you use the word "array" without using any arrays), but here's a shot:
    #!perl -l my @seq = qw/ 1 2 3 4 5 6 7 8 9 0 /; for (1 .. 5) { print "frame $_: ", getframe($_,@seq); } sub getframe { my ($n,@in) = @_; $n--; return join '', @in[ $n .. $#in ]; } __END__ frame 1: 1234567890 frame 2: 234567890 frame 3: 34567890 frame 4: 4567890 frame 5: 567890
Re: Array - Reading frame problem
by graff (Chancellor) on Jul 16, 2005 at 14:51 UTC
    I'm not sure I understand you're question. Do you want to create an array so that each element in the array contains exactly one character, in sequence, from a string? That's pretty simple with split:
    my $sequence = "1234567890"; my @chrsequence = split //, $sequence; print "array has " . scalar @chrsequence . " elements: @chrsequence\n" +;
    The first argument to split in this case is an empty regex, which happens to have the effect of splitting the input string at every character.

      Haha :) thanks graff.. but is it possible to just display the sequence from position 1 onwards and right to the end? (excluding position 0)

        You just need to learn more of the basics of perl syntax. There are lots of ways to do whatever you want with any subset of array elements:
        print "$_\n" for ( @array[1..$#array] ); # which is the same as: for my $i ( 1 .. $#array ) { print "$array[$i]\n"; } # and $" = "\n"; print "@array[1..$#array]\n";
        It is, using the slice notation already mentioned above.
        my $sequence = "1234567890"; my @chrsequence = (split //, $sequence)[1..length($sequence)-1]; print "array has " . scalar @chrsequence . " elements: @chrsequence\n" +;


        holli, /regexed monk/
Re: Array - Reading frame problem
by tlm (Prior) on Jul 16, 2005 at 13:12 UTC

    which is wrong as the "2" in "234567890" will still be in position 1.. instead of 0

    No, the "2" in "234567890" is in position 0.

    the lowliest monk

      No.. what i meant was if i apply the code $frame2 = substr($sequence, 1); to $sequence, the position of "2" will be in position "1" as i extract it using substring.
      What i meant is if there's anyway for me to extract "234567890" by using an array, instead of substr because i wan "2" to be in position 0.

        If what you mean is you want the array equivalent of substr, it's array slices. (splice looks similar to substr syntactically, but is different in that it's destructive of the source array.)
        @frame2 = @sequence[ 1 .. $#sequence ];
        The module Tie::OffsetArray could probably be used cleverly for this kind of frame-related problem.
Are you doing DNA/RNA seq analysis?
by BerntB (Deacon) on Jul 18, 2005 at 04:54 UTC
    I don't know what you are doing, but it almost sounds like you are looking for e.g. bioperl.org?

    You might also want to look at Mastering Perl for Bioinformatics from O'Reilly. (That page have a free chapter on the net about Bioperl.)

    Update:
    Hmm... I looked at your other questions (should have done that before answering, I'm still a newbie).

    You are working with DNA sequences. If you are going to do a lot of this (and isn't just trying to get help for a lab!), you probably want to read a book or two. There is a Beginning Perl for Bioinformatics. A good start is to look at O'Reilly.

      hey.. yea.. i'm doing Bioinformatics and working with DNA sequences etc. Thanks alot for the recommendations! :)