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.

···

--
Posted via http://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"]

···

On Feb 2, 10:52 am, Michael Sc <michael.schat...@gmail.com> 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.

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

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

···

--
Posted via http://www.ruby-forum.com/\.

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 via http://www.ruby-forum.com/.

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

:wink:

James Edward Gray II

···

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

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

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 }%"
}

···

On Feb 2, 4:26 pm, Michael Sc <michael.schat...@gmail.com> 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/.

James Gray wrote:

···

On Feb 6, 2007, at 9:51 AM, Drew Olson 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 Gray II

Ahh, neat, good to know.

--
Posted via http://www.ruby-forum.com/\.

William James 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, 4:26 pm, Michael Sc <michael.schat...@gmail.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

thanks
that's great to know.

···

On Feb 6, 2007, at 9:51 AM, Drew Olson 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 Gray II

--
Posted via http://www.ruby-forum.com/\.

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 "

···

On Feb 2, 9:53 pm, Michael Sc <michael.schat...@gmail.com> wrote:

William James wrote:
> On Feb 2, 4:26 pm, Michael Sc <michael.schat...@gmail.com> 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 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}

···

--
Posted via http://www.ruby-forum.com/.

Thank you very much.

···

--
Posted via http://www.ruby-forum.com/.

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?

···

--
Posted via http://www.ruby-forum.com/\.

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.

···

--
Posted via http://www.ruby-forum.com/.

Michael Sc wrote:

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?

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(P)
http://borasky-research.blogspot.com/

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

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

···

--
Posted via http://www.ruby-forum.com/\.

Drew Olson 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.

···

--
Posted via http://www.ruby-forum.com/\.