1
$\begingroup$

I am using Mathematica to post-process data and end up with machine precision artifacts that produce unwanted digits when exporting as CSV. See this example:

x=1+10^-9 -1.; ExportString[x,"CSV"] 1.000000082740371e-9 

So, I figured I use NumberForm[] to reduce the precision of x. But apparently CSV-Export does not know how to handle NumberForm (nor EngineeringForm): ExportString[NumberForm[x, {4,3}], "CSV"] produces multiline output (FullForm)

" -9\n1.000 \[CapitalATilde]\.97 10\n" 

or, with CharacterEncoding -> "ASCII",

" -9\n1.000 x 10\n" 

Not something Excel would read. I expect 1.000e-9.

As this question has been closed I cannot answer my own question, but I can still edit it:

One solution is hand-crafting the NumberFormat like this:

ExportString[ NumberForm[x, {4, 3}, NumberFormat -> (If[#3 == "", #1, Row[{#1, "e", #3}]] &)], "CSV"] 

If you only want to get rid of the unwanted digits, but do not care for a fixed number of digits you can also just use

ExportString[SetPrecision[x, 5], "CSV"] 
$\endgroup$
8
  • $\begingroup$What is the expected outpu? As for the Ã, it's likely due to some character encoding mismatch, since ExportString[NumberForm[1.2 10^-9, 4], "CSV", CharacterEncoding -> "ASCII"] works. Also note that there are quite a few questions about exporting tables/numbers to CSV :)$\endgroup$
    – Domen
    CommentedOct 18, 2024 at 18:14
  • $\begingroup$I expect 1.2e-9. Excel cannot read multi-line formatted numbers.$\endgroup$
    – Martin R
    CommentedOct 18, 2024 at 18:59
  • 1
    $\begingroup$There is nothing wrong with NumberForm. It is not intended to produce strings, but to produce a visualization in the front end. It might not be intuitive, but it's very deliberate and very consistent across all of the *Form functions. Asking ExportString to handle NumberForm is like asking it to handle Graph or Plot. The "workaround" is what I posted in my answer. You don't have to use PaddedForm if you don't want, but the point is, you probably need two steps. Step #1 is to figure out how to get your desired format as a 1-dimensional representation and step #2 is applying ToString to that.$\endgroup$
    – lericr
    CommentedOct 19, 2024 at 22:57
  • 1
    $\begingroup$I would be fine re-opening this if you provide more clarity on what you want. Also, it would be nice to understand why my solution doesn't work for you. Again, PaddedForm was just an example. It sounds like you want a variety of formatting rules, but if you can't achieve them with NumberFormat, then there is something very specific to your problem that you aren't communicating.$\endgroup$
    – lericr
    CommentedOct 19, 2024 at 23:02
  • 1
    $\begingroup$As long as the question is framed as a problem with NumberForm, or as an interaction between NumberForm and ExportString, then it should remain closed, because that is not the problem.$\endgroup$
    – lericr
    CommentedOct 19, 2024 at 23:04

1 Answer 1

2
$\begingroup$

Most of the *Form functions are intended to be used for display purposes. They just wrap the expression and the front end has rules for how to display each type of wrapper. You probably want to generate strings for exporting to CSV. The NumberFormat option to the various *Form functions is useful for defining how your "numbers" should look. So, you might try something like this:

ExportString[ToString[PaddedForm[1.2 10^-9, {5, 4}, NumberFormat -> (#1 <> "e" <> #3 &)]], "CSV"] (* " 1.2000e-9" *) 

You can adjust the formatting to whatever you want, I just made assumptions based on my interpretation of your code.

$\endgroup$
7
  • $\begingroup$Thank you, that works, but the CSV export format should take care of that!$\endgroup$
    – Martin R
    CommentedOct 18, 2024 at 19:04
  • $\begingroup$Well, based on your update with your expected output, it does take care of it if you just don't introduce NumberForm.$\endgroup$
    – lericr
    CommentedOct 18, 2024 at 19:27
  • $\begingroup$I would not use NumberForm if all my floats had only a couple of decimals. And some are small, so no scientific notation. In this case your suggestion fails. I suspect there is no nice solution...$\endgroup$
    – Martin R
    CommentedOct 19, 2024 at 22:29
  • $\begingroup$You can certainly write a function that performs different formatting based on different sized numbers, or any other discernible characteristic of the input.$\endgroup$
    – lericr
    CommentedOct 19, 2024 at 23:05
  • $\begingroup$Of course, I can write my own function. But I am surprised that apparently there is no built-in support with NumberForm not bring usable. I still don’t see why you consider this off-topic.$\endgroup$
    – Martin R
    CommentedOct 20, 2024 at 20:04

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.