Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write columns header to a csv file with Ruby?

I am having trouble writing columns to a csv file with Ruby. Below is my snippet of code.

 calc = numerator/denominator.to_f  data_out = "#{numerator}, #{denominator}, #{calc}"  File.open('cdhu3_X.csv','a+') do|hdr|       hdr << ["numerator","denominator","calculation\n"] #< column header           hdr << "#{data_out}\n"  end 

The code adds the column headers to every line and I only need it at the top of each column of data. I have searched here and other places but can't find a clear answer to how its done. Any help would be greatly appreciated.

like image 984
Joe Avatar asked Apr 09 '13 15:04

Joe


People also ask

Can CSV files have headers?

A header of the CSV file is an array of values assigned to each of the columns. It acts as a row header for the data. Initially, the CSV file is converted to a data frame and then a header is added to the data frame. The contents of the data frame are again stored back into the CSV file.

How do I make two columns into a CSV file?

csv file is a text file; you can add lines (rows) to an existing file. To add columns you need to write a whole new file. That means load the file into Python object (dataframe), make changes there, and then write the new file. Please provide a sample file/data to give you working code and avoid posting images of data.


2 Answers

I would recommend to use the CSV-library instead:

require 'csv'  CSV.open('test.csv','w',      :write_headers=> true,     :headers => ["numerator","denominator","calculation"] #< column header   ) do|hdr|   1.upto(12){|numerator|     1.upto(12){ |denominator|       data_out = [numerator, denominator, numerator/denominator.to_f]       hdr << data_out     }   } end 

If you can't use the w option and you really need the a+ (e.g., the data isn't available all at once), then you could try the following trick:

require 'csv'  column_header = ["numerator","denominator","calculation"] 1.upto(12){|numerator|   1.upto(12){ |denominator|     CSV.open('test.csv','a+',          :write_headers=> true,         :headers => column_header       ) do|hdr|           column_header = nil #No header after first insertion           data_out = [numerator, denominator, numerator/denominator.to_f]           hdr << data_out         end   } } 
like image 152
knut Avatar answered Oct 13 '22 04:10

knut


The cleanest way to do this is to open the file once, in mode 'w', write the headers, and then write the data.

If there's some technical reason that can't do this (e.g., the data isn't available all at once), then you can use the IO#tell method on the file to return the current file position. When you open the file for appending, the position is set to the end of the file, so if the current file position is zero, then the file was newly created and has no headers:

File.open('cdhu3_X.csv', 'a+') do |hdr|   if hdr.tell() == 0  # file is empty, so write header     hdr << "numerator, denominator, calculation\n"   end   hdr << "#{data_out}\n" end 
like image 37
sfstewman Avatar answered Oct 13 '22 04:10

sfstewman