Forum: Ruby Stripping columns / puts'ing columns

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0f84f5e455d71105de3f995eadaea601?d=identicon&s=25 Marc Hoeppner (lasastard)
on 2007-07-12 10:38
Hi again,

still on my quest to learn ruby ;) And yet another question - more a
general "how-to-approach" thing, though.

Let's say I have a text file with a number of rows (it's a molecular
sequence alignment, so each row = one sequence).
I am only interested in those columns in which a certain character
appears - no matter whether in all row or only one. The whole column
should then be puts'ed.

After thinking about it for a moment, my idea was to store each row in
an array, check each array position for the presence of that particular
character and, if it is, found, to puts this array field [n] and the
corresponding field from all other arrays. Now, there are a couple of
potential problems such as hitting the same column multiple times
because I search multiple arrays... But anyways, since I am rather new
to programming and ruby in particular, that will take me a while - so I
was wondering if there is a more elegant/efficient approach to this,
before I waste my time on this only to find out it doesnt work or could
be done more efficiently (wasted quite some time on another program the
other day only to find out that it can be done with grep...yuck).

/Marc
2f4d4f9c35ea851bffb9a9cc2e086365?d=identicon&s=25 Harry Kakueki (Guest)
on 2007-07-12 10:56
(Received via mailing list)
On 7/12/07, Marc Hoeppner <marc.hoeppner@molbio.su.se> wrote:
> corresponding field from all other arrays. Now, there are a couple of
> potential problems such as hitting the same column multiple times
> because I search multiple arrays... But anyways, since I am rather new
> to programming and ruby in particular, that will take me a while - so I
> was wondering if there is a more elegant/efficient approach to this,
> before I waste my time on this only to find out it doesnt work or could
> be done more efficiently (wasted quite some time on another program the
> other day only to find out that it can be done with grep...yuck).
>
> /Marc
>
Does this do what you want?

arr = [[1,7,3,4],[5,6,7,8],[9,7,3,4]]
new_arr = arr.transpose

p new_arr.select {|x| x.include?(7)}

Harry
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-07-12 11:04
(Received via mailing list)
Alle giovedì 12 luglio 2007, Marc Hoeppner ha scritto:
>
> other day only to find out that it can be done with grep...yuck).
>
> /Marc

If I understand your problem correctly, you can try this:

max_length = rows.map{|r| r.length}.max
cols = rows.map{|r| r.split('') + Array.new(max_length - r.length)
}.transpose
interesting_cols = cols.select{ |c| c.include?(interesting_character) }

Your idea is correct: transform each row from a string to an array of
characters. So, youave a nested array, with column elements inside rows.
Since you need to select character basing on columns, we need to
transpose
the outer array. This will leave you with a nested array where each
element
of the outer array is a column, on which you can use select. The only
problem
is that to use this approach, your rows need to be of the same length.
If
they aren't, then you need to add to the array obtained split another
array,
made of empty strings, whose size is the difference between the length
of the
longest line and the length of the line. At the end, you may need to
remove
those elements (you can do this with

interesting_cols.each{|c| c.delete('')}

). If all your lines have the same length, then you don't need to do
this and
the first two lines of my code become

cols = rows.map{|r| r.split('')}.transpose

I hope this helps

Stefano
0f84f5e455d71105de3f995eadaea601?d=identicon&s=25 Marc Hoeppner (lasastard)
on 2007-07-12 11:06
Stefano Crocco wrote:

> I hope this helps
>
> Stefano

Hi and thanks a lot - yes I guess that helps. The rows are of equal
length, so that wont be an issue.

Cheers,
Marc
2f4d4f9c35ea851bffb9a9cc2e086365?d=identicon&s=25 Harry Kakueki (Guest)
on 2007-07-12 11:11
(Received via mailing list)
> Does this do what you want?
>
> arr = [[1,7,3,4],[5,6,7,8],[9,7,3,4]]
> new_arr = arr.transpose
>
> p new_arr.select {|x| x.include?(7)}
>
The rows need to have the same number of elements.

Harry
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-07-12 11:31
(Received via mailing list)
2007/7/12, Marc Hoeppner <marc.hoeppner@molbio.su.se>:
>
> other day only to find out that it can be done with grep...yuck).
I'm missing one crucial bit of information: can your files grow so
large that they do not fit into memory?  If that's the case you need a
two or more phased approach.

Kind regards

robert
0f84f5e455d71105de3f995eadaea601?d=identicon&s=25 Marc Hoeppner (lasastard)
on 2007-07-12 11:47
Robert Klemme wrote:
> 2007/7/12, Marc Hoeppner <marc.hoeppner@molbio.su.se>:
>>
>> other day only to find out that it can be done with grep...yuck).
> I'm missing one crucial bit of information: can your files grow so
> large that they do not fit into memory?  If that's the case you need a
> two or more phased approach.
>
> Kind regards
>
> robert

I am using single protein alignments, so that any single row should
never exceed   ~ 2000 characters (or in other word my sequences are
rarely longer than a couple hundred characters), with 20 rows tops. So
that should not be an issue, I guess.
This topic is locked and can not be replied to.