Decimals control to the writetable to txt!

82 views (last 30 days)
abaza
abaza on 13 Feb 2017
Commented: dpb on 14 Feb 2017
Hi, I have a problem with the decimals while exporting a table to a txt file (via writetable command). Before creating the table, I round the numbers of my matrix to the 4th decimal and I create the table with my variable names etc. When I open the table in matlab workspace, everything is fine concerning the 4th decimal. Namely, when the 4th decimal does not exist, I see ZERO. However, when I export the table to txt, I do not get zero in the 4th decimal! Do you know any way to fix it?? Thank you!

Answers (2)

dpb
dpb on 13 Feb 2017
Edited: dpb on 14 Feb 2017
More than likely this is a case of display vis a vis internal storage; in general floating point values can't be stored precisely at some arbitrary number of decimal digits and when the data are output unless you control the format the full precision will be shown.
Use something like '%.4f' as a format spec and see if happiness doesn't ensue.
ADDENDUM
Actually, is documented behavior--
help writetable
...
In some cases, writetable creates a file that does not represent T exactly,
as described below. ...
* writetable writes out numeric variables using long g format, ...
Use something like--
dlmwrite('yourfile.txt',t{:,:},'\t','precision','%10.4f')
as one workaround for tab-delimited file.
ADDENDUM
As Walter notes, fprintf give complete flexibility; it's just a little harder to use as need fopen and to remember to use the .' transpose since Matlab internally is column-major storage order. dlmwrite, while a pretty klunky old routine, handles those details for you with the ability for a single format style which sounded as though was sufficient for your needs here.
  4 Comments
Walter Roberson
Walter Roberson on 14 Feb 2017
dlmwrite does not handle header columns.if you do for some reason need fixed width then you probably need fixed width on the header too. Easiest to be safe by using fprintf
dpb
dpb on 14 Feb 2017
That's true, dlmwrite won't write the header row...was that a requirement or just an artifact of had the data in a table so writetable seemed a natural?

Sign in to comment.


Peter Perkins
Peter Perkins on 14 Feb 2017
There's not enough information to know what's going on here. This
>> t = array2table(round(randn(10,5),4)) % or reshape(1e-4:1e-4:1,1000,10)
>> writetable(t,'t.txt')
creates a table that displays with no more than four digits after the decimal, and creates a text file where that's also true. Is that not what you are seeing? What exactly is in the table you have?
As dpb points out, floating point will rarely be able to represent arbitrary decimal values exactly. Perhaps that's what's going on. But even this
>> t = array2table(round(1e12*randn(10,5),4))
where the fourth digit is essentially on the order of round-off, still displays and writes out with no more than four digits.
  4 Comments
Walter Roberson
Walter Roberson on 14 Feb 2017
If you have a situation where you need a fixed width format you should probably fprintf using the exact format you need
Peter Perkins
Peter Perkins on 14 Feb 2017
OK, sorry, I completely misinterpreted the problem. If having the trailing zeros is important, then I do think you will want to rely on some form '%.4f' format as dpb and Walter suggest.
One possibility would be to create a temporary table by replacing each numeric variable in the table with text, like this:
t.X = cellstr(num2str([1;2;3],'%.4f'))
and then write out that temporary table using writetable.
But it does seem rather unusual that a spreadsheet would not be able to recognize 4.123 as exactly the same thing as 4.1230. I'm not sure why that would be, but perhaps you could write out your original table with writetable, but with 'FileType','spreadsheet'. That will create a .xlsx file, which I imagine both Numbers and Calc can import.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!