File Exchange Pick of the Week

Our best user submissions

Writing A Cell Array – A Comparison

Posted by Sean de Wolski,

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:

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.


Get the MATLAB code

Published with MATLAB® R2015a

Note

Comments are closed.