2

All,
I have a csv file with 2 columns.I have to plot a graph based on this data. Column1(X axis) is simple incrementing numbers and column 2 has random positive integers(Y axis). A sample data looks like this

1 95
2 95
3 95
4 85
5 81
6 81
7 84
8 92
9 85

I have to read the contents of the file and display it in a graph. I'm an absolute newb in Ruby. Here is the code I'm working on (not mine):

data = [] fields = [] csv_data = {} File.open(CSV_FILENAME, "r").each_line do |line| line = line.strip.split(',') csv_data[line.first.to_s] = line.last end csv_data.each do |row| content = row.first log "Creating data point: #{content}" fields << content data << row.last.to_i end 

The output I see in terminal is totally different. Here is the output I see:
Creating data point: 6
Creating data point: 7
Creating data point: 8
Creating data point: 9
Creating data point: 1
Creating data point: 2
etc.

As result the graph is also not correct. I want the output to be in this form:
Creating data point: 1
Creating data point: 2
Creating data point: 3
etc.

What's wrong in this piece of code?

2 Answers 2

3

Hashes (identified by {}) are not ordered data structures. You need to use an Array if you want an ordered listing.

I'd use something resembling the following:

#!/usr/bin/env ruby filename = 'test.csv' graph_data = {} File.open(filename, 'r').each_line do |line| line = line.strip.split ',' graph_data[line.first.to_s] = line.last.to_s end graph_data.each_pair do |x,y| puts "#{x} => #{y}" end # Graph your data points here... 

When you're graphing the points, the order doesn't matter since they'll end up in the correct place on the plot regardless.

Sign up to request clarification or add additional context in comments.

2 Comments

I used arrays to store the data points and that works like a charm.
As Knut said the hash was not ordered for ruby 1.8 but was ordered in 1.9.3. From the documentation: Hashes enumerate their values in the order that the corresponding keys were inserted.
1

As already mentioned: Hashes are not ordered (at least in ruby 1.8).

Ruby 1.9 has ordered hashes, so an upgrade may help for the sequence.

Or with ruby 1.8 you may change to arrays (see other answers) or my recommendation: sort the hash:

csv_data.sort.each do |row| #... 

Another problem: Did you check the content of csv_data?

When I use your program and data I get {"1 95"=>"1 95", "2 95"=>"2 95", .... I think. thats not the result you want.

You make a split(',') but the data you showed are space-separated, so I would use split(' ').

When you did this, csv_data contains the data, you don't need the variables data or fields.

The following MWE replaces the file with DATA, but it shows the principle:

csv_data = {} #~ File.open(CSV_FILENAME, "r").each_line do |line| DATA.each_line do |line| line = line.strip.split(' ') csv_data[line.first.to_s] = line.last.to_i end #check the data #~ p csv_data csv_data.sort.each do |row, col| puts "Point: #{row} - #{col}" end #If fields = csv_data.keys data = csv_data.values __END__ 1 95 2 95 3 95 4 85 5 81 6 81 7 84 8 92 9 85 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.