Writing A Cell Array – A Comparison
Sean's pick this week is a comparison of a few cell-writing functions.
Contents
Background
There are many high-level functions for writing common datatypes to text file formats such as writetable, csvwrite, and dlmwrite. However, you might have noticed that none of these work on cell arrays. Since cell arrays can and often do contain highly heterogenous data, you'll often need to use lower-level functionality like fprintf to write them out given the knowledge of what the cell contains. My pick today is a comparison of a few files that have tried to automate this while trying to do the "write" thing.
Selected Entries
Below, I've selected a few files to compare based on a quick search and the fact that they're all covered under the BSD license:
- Write-cell-array-to-text-file by Roland Pfister (dlmcell).
- Write-a-cell-array-to-a-text-file by Ameya Deoras (fwritecell).
- Cell-array-to-csv-file--cell2csv-m by Sylvain Fiedler (cell2csv).
- Cell-array-to-csv-file--improved-cell2csv-m by Jerry (impcell2csv renamed to avoid collision).
- Cellwrite by Francis Barnhart (cellwrite).
Test 1: Simple
This first test is simple, write a cell array of numeric values that doesn't even have to be a cell array to a text file:
C = num2cell(magic(5)); disp(C)
[17] [24] [ 1] [ 8] [15] [23] [ 5] [ 7] [14] [16] [ 4] [ 6] [13] [20] [22] [10] [12] [19] [21] [ 3] [11] [18] [25] [ 2] [ 9]
mkdir Test1 dlmcell('.\Test1\dlmcell.csv',C) fwritecell('.\Test1\fwritecell.csv',C) cell2csv('.\Test1\cell2csv.csv',C,',') impcell2csv('.\Test1\impcell2csv.csv',C,',') cellwrite('.\Test1\cellwrite.csv',C)
All of the files pass!
Test 2: Mixed Data
This test mixes floating point data, integer data and string data in one cell array:
C = {pi, 'Sean', uint8(42); uint8(42), exp(1), exp(45); 'MaTLaB','Test 2', 1; -1.23 -exp(45) 19}; disp(C)
[ 3.1416] 'Sean' [ 42] [ 42] [ 2.7183] [3.4934e+19] 'MaTLaB' 'Test 2' [ 1] [-1.2300] [-3.4934e+19] [ 19]
mkdir Test2 dlmcell('.\Test2\dlmcell.csv',C) fwritecell('.\Test2\fwritecell.csv',C) cell2csv('.\Test2\cell2csv.csv',C,',') impcell2csv('.\Test2\impcell2csv.csv',C,',') cellwrite('.\Test2\cellwrite.csv',C)
fwritecell was unable to resolve this cell array because it needs consistent formatting. Because it relies on cell2mat, this continues to pop up. The others pass.
Test 3: Speed
This test is for speed. I'm going to write a large cell array to see what happens.
C = repmat(C,1000,10);
disp('Size of C')
disp(size(C))
Size of C 4000 30
mkdir Test3 t = nan(1,5); tic dlmcell('.\Test3\dlmcell.csv',C) t(1) = toc; tic cell2csv('.\Test3\cell2csv.csv',C,',') t(3) = toc; tic impcell2csv('.\Test3\impcell2csv.csv',C,',') t(4) = toc; tic cellwrite('.\Test3\cellwrite.csv',C) t(5) = toc
t =
11.2884 NaN 16.8843 8.3786 7.4123
cellwrite is the winner by just under a second over impcell2csv!
Test 4: Mixed sized Data
Here we will have a different sized cells.
C = num2cell(magic(2));
C{2} = C;
C{3} = 'intlinprog';
disp(C)
[ 1] 'intlinprog' {2x2 cell} [ 2]
mkdir Test4 dlmcell('.\Test4\dlmcell.csv',C) cell2csv('.\Test4\cell2csv.csv',C,',') impcell2csv('.\Test4\impcell2csv.csv',C,',') cellwrite('.\Test4\cellwrite.csv',C)
The winner here is going to be impcell2csv with dlmcell coming in a close second. impcell2csv wrote NA in the spot of the nested cell, dlmcell left it blank. The others gave non-descript errors with the file partially written.
Challenge Does anyone know of a file that will handle this? Perhaps padding with extra commas or providing other options?
Test 5: N-Dimensional Arrays
Here we will have a three-d cell array.
C = {pi, 'Sean', uint8(42); uint8(42), exp(1), exp(45); 'MaTLaB','Test 2', 1; -1.23 -exp(45) 19}; C = cat(3,C,C); disp(C)
(:,:,1) = [ 3.1416] 'Sean' [ 42] [ 42] [ 2.7183] [3.4934e+19] 'MaTLaB' 'Test 2' [ 1] [-1.2300] [-3.4934e+19] [ 19] (:,:,2) = [ 3.1416] 'Sean' [ 42] [ 42] [ 2.7183] [3.4934e+19] 'MaTLaB' 'Test 2' [ 1] [-1.2300] [-3.4934e+19] [ 19]
mkdir Test5 dlmcell('.\Test5\dlmcell.csv',C) cell2csv('.\Test5\cell2csv.csv',C,',') impcell2csv('.\Test5\impcell2csv.csv',C,',') cellwrite('.\Test5\cellwrite.csv',C)
impcell2csv and cellwrite did the same thing here, append the second page to the right of the first page. I guess that's a tie, cell2csv and dlmcell both ignored the second page altogether.
Test 6: Help/Flexibilty
How's the help/flexibility?
help dlmcell
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> %% <><><><><> dlmcell - Write Cell Array to Text File <><><><><> % <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> % Version: 01.06.2010 % (c) Roland Pfister % roland_pfister@t-online.de % ...with many thanks to George Papazafeiropoulos % for his corrections and improvements. % 1. Synopsis % % A single cell array is written to an output file. Cells may consist of % any combination of (a) numbers, (b) letters, or (c) words. The inputs % are as follows: % % - file The output filename (string). % - cell_array The cell array to be written. % - delimiter Delimiter symbol, e.g. ',' (optional; % default: tab ('\t'}). % - append '-a' for appending the content to the % output file (optional). % % 2. Example % % mycell = {'Numbers', 'Letters', 'Words','More Words'; ... % 1, 'A', 'Apple', {'Apricot'}; ... % 2, 'B', 'Banana', {'Blueberry'}; ... % 3, 'C', 'Cherry', {'Cranberry'}; }; % dlmcell('mytext.txt',mycell); % % <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> %
help fwritecell
FWRITECELL writes formatted data from a cell array to a text file. fwritecell(filename, format, data) writes data using the C language conversion specifications in variable "format" as with SPRINTF Example: fwritecell('textfile1.txt','%2d %1d %21s %8.5f',C); fwritecell(filename, data) writes data using a fixed width format padded with whitespace. Note that the decimal point for floating point numbers may not be aligned
help cell2csv
Writes cell array content into a *.csv file. CELL2CSV(fileName, cellArray, separator, excelYear, decimal) fileName = Name of the file to save. [ i.e. 'text.csv' ] cellArray = Name of the Cell Array where the data is in separator = sign separating the values (default = ';') excelYear = depending on the Excel version, the cells are put into quotes before they are written to the file. The separator is set to semicolon (;) decimal = defines the decimal separator (default = '.') by Sylvain Fiedler, KA, 2004 updated by Sylvain Fiedler, Metz, 06 fixed the logical-bug, Kaiserslautern, 06/2008, S.Fiedler added the choice of decimal separator, 11/2010, S.Fiedler
help impcell2csv
% Writes cell array content into a *.csv file. % % CELL2CSV(fileName, cellArray[, separator, excelYear, decimal]) % % fileName = Name of the file to save. [ e.g. 'text.csv' ] % cellArray = Name of the Cell Array where the data is in % % optional: % separator = sign separating the values (default = ',') % excelYear = depending on the Excel version, the cells are put into % quotes before they are written to the file. The separator % is set to semicolon (;) (default = 1997 which does not change separator to semicolon ;) % decimal = defines the decimal separator (default = '.') % % by Sylvain Fiedler, KA, 2004 % updated by Sylvain Fiedler, Metz, 06 % fixed the logical-bug, Kaiserslautern, 06/2008, S.Fiedler % added the choice of decimal separator, 11/2010, S.Fiedler % modfiedy and optimized by Jerry Zhu, June, 2014, jerryzhujian9@gmail.com % now works with empty cells, numeric, char, string, row vector, and logical cells. % row vector such as [1 2 3] will be separated by two spaces, that is "1 2 3" % One array can contain all of them, but only one value per cell. % 2x times faster than Sylvain's codes (8.8s vs. 17.2s): % tic;C={'te','tm';5,[1,2];true,{}};C=repmat(C,[10000,1]);cell2csv([datestr(now,'MMSS') '.csv'],C);toc;
help cellwrite
CELLWRITE Write a cell array to a comma separated value file. CELLWRITE(FILENAME, C) writes cell array C into FILENAME as comma separated values. NOTE: This function is not completely compatible with CSVWRITE. Offsets are not supported and 0 values are not omitted. See also CSVWRITE, CSVREAD, DLMREAD, DLMWRITE, WK1READ, WK1WRITE.
The help for all of them is good. I like dlmcell's ability to append, and I like impcell2csv's description of the enhancements though the help is mostly borrowed from cell2csv.
Comments
Do you use cell arrays to store data? If so, do you need to write them out to text often? Have you ever written your own fprintf wrapper or used one of the above files or another that I didn't see? Let us know here or leave a comment for one of the authors above on their File Exchange entry page.
- Category:
- Picks
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.