Writing CSV files with fixed decimal format

Any option to CSV.write with a format string (e.g. "%.4f")?

1 Like

I don’t know about CSV.write, but would it work to pre-format the string? I’m thinking something like

using CSV
using Printf
x = 3
CSV.write( @sprintf("%.4f", x)) # Note:I don't recall the CSV.write syntax.

This should be identical to having formatted strings in CSV.write I imagine.

I could write a small function to format all floating point numbers in the table, but I was looking for a specific CSV.jl option. The docs don’t mention it, so I am assuming it is not there yet.

1 Like

I haven’t seen such an option with CSV.jl, and typically do this:

# many table types work – rowtable, columntable, StructArray, DictArray, some others
julia> tbl = (a=1:3, b=rand(3), c=string.(1:3))

julia> using AccessorsExtra
julia> roundedtbl = @modify(x -> @sprintf("%.3f", x), tbl |> RecursiveOfType(Real))
# roundedtbl is the same type of table, but with reals converted to strings

julia> roundedtbl |> CSV.write(...)

Works fine unless you have fancy number types where rounding is more involved. Also, the conversion is not specific to CSV or tables at all, supports basically any struct.

CSV.jl has a transform option that can be used with a formatter.
For example:

using CSV, Tables, Printf

M = [rand(5,3) "S" .* string.(1:5)]

transform(col,val) = val
transform(col,val::Float64) = @sprintf("%.2f", val)
CSV.write("formated_floats.csv", Tables.table(M), transform=transform)
5 Likes

Thank you @rafael.guerra , that seems like the best available option. Perhaps the maintainers of CSV.jl can introduce a new numformat similar to dateformat that calls transform as explained above.

This is a big pain point for me recently. PrettyTables.jl has good capabilities in this area, but if you are outputting a custom table (rather than using PrettyTables.jl) it is cumbersome to control the precision of output. I’ve resorted to wrapping every number in a formatting function that I supply via keyword argument.

Compounding the problem is that it does not appear to be possible to programmatically vary the format string in @sprintf

Have you looked at Printf.Format()?
For example:

using Printf
w, d = 12, 3
fmt = Printf.Format("%$(w).$(d)f")
Printf.format(fmt, 1e4/rand())