# Writing CSV files with fixed decimal format

**URL:** <https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571>\
**Category:** Data\
**Tags:** question, package, csv, formatting\
**Created:** [November 22, 2023, 12:21pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571 "2023-11-22T12:21:07Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [November 22, 2023, 12:21pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/1 "2023-11-22T12:21:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![mihalybaci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mihalybaci/32/13528_2.png) [@mihalybaci](https://discourse.julialang.org/u/mihalybaci)\
**Post date:** [November 22, 2023, 12:29pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/2 "2023-11-22T12:29:50Z")

</div>

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

```julia
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.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [November 22, 2023, 12:36pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/3 "2023-11-22T12:36:55Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [November 22, 2023, 1:25pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/4 "2023-11-22T13:25:01Z")

</div>

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

```julia
# 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.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [November 22, 2023, 3:03pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/5 "2023-11-22T15:03:29Z")

</div>

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

```julia
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)

```

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [November 22, 2023, 4:52pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/6 "2023-11-22T16:52:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [November 22, 2023, 5:19pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/7 "2023-11-22T17:19:04Z")

</div>

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`…

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [November 22, 2023, 5:38pm UTC](https://discourse.julialang.org/t/writing-csv-files-with-fixed-decimal-format/106571/8 "2023-11-22T17:38:58Z")

</div>

> [@tbeason](#):
>
> 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:

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

```
