Beginner questions: sorting csv files

Hello,
I am a newbie with Ruby and I had a couple of questions while
manipulating csv files. How would I do a multiple column sort? I have
a file that needs to be sorted by the 3rd column, then 1st, then second.
I understand how to do one sort for the csv file but I was unsure of how
to do multiple.

Also,How would I to do a percentage change between two numbers in a
column?

Thank you very much. I know these are easy questions but I am still
learning how to program in Ruby.

On Feb 2, 10:52 am, Michael Sc [email protected] wrote:

Thank you very much. I know these are easy questions but I am still
learning how to program in Ruby.


Posted viahttp://www.ruby-forum.com/.

[ [9,‘ash’,‘cube’],
[8,‘blue’,‘cube’],
[3,‘mauve’,‘frustrum’],
[8,‘green’,‘cube’]
].sort_by{|a| a.values_at( 2,0,1 ) }.
each{|a| p a }

— output -----
[8, “blue”, “cube”]
[8, “green”, “cube”]
[9, “ash”, “cube”]
[3, “mauve”, “frustrum”]

Thank you very much. I did not realize it was so simple. Do you know
how to refer to prior lines to make calculations?

William J. wrote:

On Feb 2, 4:26 pm, Michael Sc [email protected] wrote:

Thank you very much. I did not realize it was so simple. Do you know
how to refer to prior lines to make calculations?


Posted viahttp://www.ruby-forum.com/.

a =
[ [‘alloy’, 1.414],
[‘malign’, 1.732],
[‘smudge’, 2.0],
[‘smack’, 2.236]
]

0.upto( a.size - 2 ) {|i|
puts “Change from line #{i} to line #{i+1}:
#{ (a[i+1][1] - a[i][1]) / a[i][1] * 100 }%”
}
Thank you very much. I just had one more question about this then. How
would I write this to its own csv file?

require ‘csv’
outfile = File.open(‘newfile.csv’, ‘wb’)
x=CSV.open(“oldfile.csv”, “r”)
x.sort_by{|a| a.values_at( 2,0,1 ) }.each{|a| outfile.print a }
outfile.close

I tried outfile.p(doesn’t work), outfile.print(takes out the commas) and
outfile.put(takes out the breaks). I know this should be incredibly
easy but I am clearly missing something.

On Feb 2, 9:53 pm, Michael Sc [email protected] wrote:

[‘malign’, 1.732],
would I write this to its own csv file?

require ‘csv’
outfile = File.open(‘newfile.csv’, ‘wb’)
x=CSV.open(“oldfile.csv”, “r”)
x.sort_by{|a| a.values_at( 2,0,1 ) }.each{|a| outfile.print a }
outfile.close

I tried outfile.p(doesn’t work), outfile.print(takes out the commas) and
outfile.put(takes out the breaks). I know this should be incredibly
easy but I am clearly missing something.

Before writing each record (i.e., each array of fields) to the file,
it must first be converted to a proper csv string.
The ‘csv’ package has a method for doing this, I presume.

If you don’t wan’t to use that, try this:

class Array
def to_csv
s = ‘’
map { |item|
str = item.to_s
# Quote the string if it contains the field-separator or
# a " or a newline or a carriage-return, or if it has leading or
# trailing whitespace.
if str.index( “,” ) or /^\s|["\r\n]|\s$/.match(str)
str = ‘"’ + str.gsub( /"/, ‘""’ ) + ‘"’
end
str
}.join( “,” )
end
end

puts [ 674, “yes”, “Jones,Tom”, ‘foo"bar’, " space " ].to_csv

— output -----
674,yes,“Jones,Tom”,“foo”“bar”," space "

Thank you very much.

On Feb 2, 4:26 pm, Michael Sc [email protected] wrote:

Thank you very much. I did not realize it was so simple. Do you know
how to refer to prior lines to make calculations?


Posted viahttp://www.ruby-forum.com/.

a =
[ [‘alloy’, 1.414],
[‘malign’, 1.732],
[‘smudge’, 2.0],
[‘smack’, 2.236]
]

0.upto( a.size - 2 ) {|i|
puts “Change from line #{i} to line #{i+1}:
#{ (a[i+1][1] - a[i][1]) / a[i][1] * 100 }%”
}

Hey,
I just had another question on these csv files. Is there anyway I could
save sorted files using the fastercsv library? Thanks again for all of
the help. I am having trouble figuring out how to use the libraries.

Michael Sc wrote:

Hey,
I just had another question on these csv files. Is there anyway I could
save sorted files using the fastercsv library? Thanks again for all of
the help. I am having trouble figuring out how to use the libraries.

Assuming your csv file is stored as “my_array”:

require ‘rubygems’
require ‘faster_csv’

FCSV.open(“output.csv”,“w”) do |out|
my_array.each{|row| out << row}
end

Michael Sc wrote:

Hello,
I am a newbie with Ruby and I had a couple of questions while
manipulating csv files. How would I do a multiple column sort? I have
a file that needs to be sorted by the 3rd column, then 1st, then second.
I understand how to do one sort for the csv file but I was unsure of how
to do multiple.

Also,How would I to do a percentage change between two numbers in a
column?

Thank you very much. I know these are easy questions but I am still
learning how to program in Ruby.

Come to think of it, I’d do the whole thing using FasterCSV. When
available, I like to use a well known library where the hard work has
already been done for me :slight_smile:

require ‘rubygems’
require ‘faster_csv’

mycsv = FCSV.read(“myfile.csv”)

FCSV.open(“output.csv”,“w”) do |out|
mycsv.sort{|a,b| [a[2],a[0],a[1]] <=> [b[2],b[0],b[1]]}.each |row|
out << row
end
end

Drew O. wrote:

Assuming your csv file is stored as “my_array”:

require ‘rubygems’
require ‘faster_csv’

FCSV.open(“output.csv”,“w”) do |out|
my_array.each{|row| out << row}
end
Thank you very much.

On Feb 6, 2007, at 9:51 AM, Drew O. wrote:

mycsv.sort{|a,b| [a[2],a[0],a[1]] <=> [b[2],b[0],b[1]]}.each |row|

mycsv.sort_by { |row| row.values_at(2, 0, 1) }.each do |row|

:wink:

James Edward G. II

On Feb 6, 2007, at 9:51 AM, Drew O. wrote:

mycsv.sort{|a,b| [a[2],a[0],a[1]] <=> [b[2],b[0],b[1]]}.each |row|

mycsv.sort_by { |row| row.values_at(2, 0, 1) }.each do |row|

:wink:

James Edward G. II
thanks
that’s great to know.

on the daily return, I wanted to define two if statements so that two
columns had to equal in order to do take the percantage change function.
Does anyone have any ideas on this?
I tried to do this. Thanks again for the help.

0.upto( a.size - 2 ) {|i|
(a[i][1]==a[i+1][1] and a[i][2]==a[i+1][2]) (a[i+1][3] - a[i][3]) /
a[i][3] * 100}

James G. wrote:

On Feb 6, 2007, at 9:51 AM, Drew O. wrote:

mycsv.sort{|a,b| [a[2],a[0],a[1]] <=> [b[2],b[0],b[1]]}.each |row|

mycsv.sort_by { |row| row.values_at(2, 0, 1) }.each do |row|

:wink:

James Edward G. II

Ahh, neat, good to know.

Michael Sc wrote:

on the daily return, I wanted to define two if statements so that two
columns had to equal in order to do take the percantage change function.
Does anyone have any ideas on this?
I tried to do this. Thanks again for the help.

0.upto( a.size - 2 ) {|i|
(a[i][1]==a[i+1][1] and a[i][2]==a[i+1][2]) (a[i+1][3] - a[i][3]) /
a[i][3] * 100}

Also, Does anyone have any recommendations about books that have a large
discussion of ruby for math purposes?

Michael Sc wrote:

Also, Does anyone have any recommendations about books that have a large
discussion of ruby for math purposes?

There is a SciRuby web site at

http://sciruby.codeforpeople.com/sr.cgi/FrontPage


M. Edward (Ed) Borasky, FBG, AB, PTA, PGS, MS, MNLP, NST, ACMC§
http://borasky-research.blogspot.com/

If God had meant for carrots to be eaten cooked, He would have given
rabbits fire.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs