Clear Filters
Clear Filters

writetable does not replace file

87 views (last 30 days)
Hi,
I just observed a somewhat confusing behaviour with the writetable function in matlab. Here is a simple code to explain it
t = T(1:10,:)
writetable(t, '/tmp/test.xlsx')
writetable(t, '/tmp/test1.xlsx')
t = t([2 4 1 3 5],:)
writetable(t, '/tmp/test.xlsx')
writetable(t, '/tmp/test2.xlsx')
now test2.xlsx is a table with 5 rows, as expected.
test.xlsx is a table with 10 rows, wheres the first 5 equal test2.xlsx and the last 5 equal test1.xlsx
I would expect test.xlsx should be the same as test2.xlsx. I had a misunderstanding in a collaboration with colleagues which was close to publish erroneous data.
I there a way to change this?
I'm using matlab on ubuntu 18.04 with libreoffice.
Thanks for any help
Dom
  2 Comments
Stephen23
Stephen23 on 7 Jan 2019
Edited: Stephen23 on 7 Jan 2019
"...table.xlsx is a table..."
Your code does not write any file named table.xlsx
"table.xlsx is a table with 10 rows, wheres the first 5 equal test2.xlsx and the last 5 equal test1.xlsx"
As far as I can tell test2.xlsx will have five rows and test2.xlsx will have ten rows. How do you expect ten rows plus five rows to equal ten rows?
"I would expect table.xlsx should be the same as table2.xlsx"
Your code does not write any file named table2.xlsx
Please ensure your question is consistent so that we can understand what you are doing and what you expect to happen.
Dominik
Dominik on 7 Jan 2019
Edited: Dominik on 7 Jan 2019
Agreed, this was confusing. should be more comprehensive now.
Thanks Stephen
I added the files for better understanding:
test.xlsx:
ID data
1110001J03Rik 8.89677566558355
1110008J03Rik 7.96109736966
0610012G03Rik 9.63646621146629
1110008F13Rik 11.1951001197166
1110008P14Rik 9.66131244366283
1110020G09Rik 10.1350186373341
1190005I06Rik 8.31154145339037
1190007I07Rik 7.80357654149566
1300010F03Rik 11.8919227299957
1300018J18Rik 10.1833018264752
test1.xlsx
ID data
0610012G03Rik 9.63646621146629
1110001J03Rik 8.89677566558355
1110008F13Rik 11.1951001197166
1110008J03Rik 7.96109736966
1110008P14Rik 9.66131244366283
1110020G09Rik 10.1350186373341
1190005I06Rik 8.31154145339037
1190007I07Rik 7.80357654149566
1300010F03Rik 11.8919227299957
1300018J18Rik 10.1833018264752
test2.xlsx
ID data
1110001J03Rik 8.89677566558355
1110008J03Rik 7.96109736966
0610012G03Rik 9.63646621146629
1110008F13Rik 11.1951001197166
1110008P14Rik 9.66131244366283

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 7 Jan 2019
Edited: Stephen23 on 7 Jan 2019
According to the writetable help, "If filename is the name of an existing spreadsheet file, then writetable writes a table to the specified location, but does not overwrite any values outside that range", and that is exactly what you are observing:
  1. write ten values to a (new?) spreadsheet.
  2. write five values to a (now already existing) spreadsheet. According to the documentation this will add those five values to the default location, as in your code and leave all other existing values unchanged.
  3. thus you still see five of the values from step 1. (the ones not overwritten by step 2.), and five values from step 2..
So far it seems to be behaving as described in the documentation.
While this might be useful in some situations clearly in other cases (like yours) it would be useful to delete any existing content before writing the new content, but there does not currently seem to be an option for this. I suggest that you make an enhancement request (with a link to this thread), as I am sure that others would also find this a useful option.
  3 Comments
Philip Borghesani
Philip Borghesani on 7 Jan 2019
(this comment double posted in both answers)
Interesting, I entered a bug report for the documentation about this, I think it should be spelled out more explicity in the help as well as being bolded in the doc.
The enhancment to add an overwite mode exists already in our system. Feel free to contact support and add a bit more push for an enhancment and I will push a bit.
Antoine Skaf
Antoine Skaf on 14 Oct 2020
FYI, you can set the 'WriteMode' option to 'overwritesheet' for WRITETABLE when writing to an Excel file as of R2020a. From the Doc:
'overwritesheet' — Clear the specified sheet and write the input data to the cleared sheet.
  • If you do not specify a sheet, then the writing function clears the first sheet and writes the input data to it.

Sign in to comment.

More Answers (1)

Dominik
Dominik on 7 Jan 2019
Edited: Dominik on 7 Jan 2019
OK I see. this is the doc file, however the help writetable is misleading to me.
This is different from what I get:
writetable overwrites any existing file
which writetable
/usr/local/MATLAB/R2018b/toolbox/matlab/iofun/writetable.m
help writetable:
writetable Write a table to a file.
writetable(T) writes the table T to a comma-delimited text file. The file name is
the workspace name of the table T, appended with '.txt'. If writetable cannot
construct the file name from the table input, it writes to the file 'table.txt'.
writetable overwrites any existing file.
writetable(T,FILENAME) writes the table T to the file FILENAME as column-oriented
data. writetable determines the file format from its extension. The extension
must be one of those listed below.
writetable(T,FILENAME,'FileType',FILETYPE) specifies the file type, where
FILETYPE is one of 'text' or 'spreadsheet'.
writetable writes data to different file types as follows:
.txt, .dat, .csv: Delimited text file (comma-delimited by default).
writetable creates a column-oriented text file, i.e., each column of each
variable in T is written out as a column in the file. T's variable names
are written out as column headings in the first line of the file.
Use the following optional parameter name/value pairs to control how data
are written to a delimited text file:
'Delimiter' The delimiter used in the file. Can be any of ' ',
'\t', ',', ';', '|' or their corresponding names 'space',
'tab', 'comma', 'semi', or 'bar'. Default is ','.
'WriteVariableNames' A logical value that specifies whether or not
T's variable names are written out as column headings.
Default is true.
'WriteRowNames' A logical value that specifies whether or not T's
row names are written out as first column of the file.
Default is false. If the 'WriteVariableNames' and
'WriteRowNames' parameter values are both true, T's first
dimension name is written out as the column heading for
the first column of the file.
'QuoteStrings' A logical value that specifies whether to write
text out enclosed in double quotes ("..."). If
'QuoteStrings' is true, any double quote characters that
appear as part of a text variable are replaced by two
double quote characters.
'DateLocale' The locale that writetable uses to create month and
day names when writing datetimes to the file. LOCALE must
be a character vector or scalar string in the form xx_YY.
See the documentation forDATETIME for more information.
'Encoding' The encoding to use when creating the file.
Default is 'system' which means use the system's default
file encoding.
.xls, .xlsx, .xlsb, .xlsm, .xltx, .xltm: Spreadsheet file.
writetable creates a column-oriented spreadsheet file, i.e., each column
of each variable in T is written out as a column in the file. T's variable
names are written out as column headings in the first row of the file.
Use the following optional parameter name/value pairs to control how data
are written to a spreadsheet file:
'WriteVariableNames' A logical value that specifies whether or not
T's variable names are written out as column headings.
Default is true.
'WriteRowNames' A logical value that specifies whether or not T's row
names are written out as first column of the specified
region of the file. Default is false. If the
'WriteVariableNames' and 'WriteRowNames' parameter values
are both true, T's first dimension name is written out as
the column heading for the first column.
'DateLocale' The locale that writetable uses to create month and day
names when writing datetimes to the file. LOCALE must be
a character vector or scalar string in the form xx_YY.
Note: The 'DateLocale' parameter value is ignored
whenever dates can be written as Excel-formatted dates.
'Sheet' The sheet to write, specified the worksheet name, or a
positive integer indicating the worksheet index.
'Range' A character vector or scalar string that specifies a
rectangular portion of the worksheet to write, using the
Excel A1 reference style.
'UseExcel' A logical value that specifies whether or not to create the
spreadsheet file using Microsoft(R) Excel(R) for Windows(R). Set
'UseExcel' to one of these values:
true - Opens an instance of Microsoft
Excel to write (or read) the file.
This is the default setting for
Windows systems with Excel
installed.
false - Does not open an instance of
Microsoft Excel to write (or read)
the file. Using this setting may
cause the data to be written
differently for files with live
updates (e.g. formula evaluation
or plugins).
In some cases, writetable creates a file that does not represent T exactly, as
described below. If you use TABLE(FILENAME) to read that file back in and create
a new table, the result may not have exactly the same format or contents as the
original table.
* writetable writes out numeric variables using long g format, and
categorical or character variables as unquoted text.
* For non-character variables that have more than one column, writetable
writes out multiple delimiter-separated fields on each line, and constructs
suitable column headings for the first line of the file.
* writetable writes out variables that have more than two dimensions as two
dimensional variables, with trailing dimensions collapsed.
* For cell-valued variables, WRITE writes out the contents of each cell
as a single row, in multiple delimiter-separated fields, when the contents are
numeric, logical, character, or categorical, and writes out a single empty
field otherwise.
Save T as a mat file if you need to import it again as a table.
  9 Comments
Les Beckham
Les Beckham on 1 Feb 2022
I agree with Walter's comments. However, I agree with OP and with Ron Fredricks that the message displayed by uiputfile() is misleading/confusing.
Perhaps if the message was "do you want to select this existing file" instead of "do you want to replace this file" it would make more sense, since what uiputfile() does is just select a file and return its name. It never "replaces" any file.
In fact, the name of this function is, in itself, pretty misleading as it doesn't ever "put" any file anywhere.
Obviously this is confusing and should be clarified either in the documentation or by changing the message displayed by the function itself.
My 2 cents.
Ron Fredericks
Ron Fredericks on 2 Feb 2022
Thank you all for looking into my uiputfile with excel's writematrix (or writetable) function. I have taken note of Walter's comments and rewrote my code to avoid this issue. Yet I also agree with Les that the wording (and even the name itsefl) for uiputfile needs a little work to avoid confusion for new users.
My updated code...
investigator = 'dummy value for this test code';
filter = {'*.xlsx'};
[filename,filepath] = uiputfile(filter);
if filename==0
% User aborted or canceled uiputfile, so just return without warning
xWarning = '';
return
end
% Test for requested file to save already exists and is currently open.
if isfile(filename)
[fid, ~] = fopen([filepath filename],'a');
if fid==-1
% Issue warning to user that excel file to be replaced is open,
% and therefore can not be replaced.
xWarning = filename;
return
else
xWarning = '';
fclose(fid);
end
end
lineNum = 1;
infoCol = 'B';
% First use of writematrix includes request to replace file if it
% exists.
writematrix(investigator,[filepath filename],'Sheet',1, ...
'Range',[infoCol num2str(lineNum)],'WriteMode', 'replacefile')

Sign in to comment.

Tags

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!