Search code examples
arraysmatlabtextscan

textscan() reading result is a nested cell array?


I have a data file containing 100 lines with the following format

0,device1,3
1,device2,33
2,device3,3
3,device4,34
...
99,device100,36

Now I wish to read them into a 100x3 cell array in MATLAB. I did the following:

allData = textscan(fID,'%s %s %f', 'delimiter', ',');

Then, I noticed that allData is a 1x3 cell array with each item being another 100x1 cell array. (The first two columns are string-type cell arrays, whereas the third column is double-type cell array)

In other words, the reading result is a nested array, which I don't want.

How may I achieve 100x3 cell array directly while reading?


Solution

  • With that textscan, the variable allData looks something like (just 4 rows) this:

    allData = 
        {4x1 cell}    {4x1 cell}    [4x1 double]
    

    You can only merge into a single cell array directly with textscan via the 'CollectOutput' option when all data has the same type.

    One possible workaround, which unfortunately converts all numeric data to double (not a problem in your case),

    C = cell(numel(allData{1}),numel(allData));
    areCells = cellfun(@iscell,allData);
    C(:,areCells) = [allData{areCells}];
    C(:,~areCells) = num2cell([allData{~areCells}])
    C = 
        '0'    'device1'    [ 3]
        '1'    'device2'    [33]
        '2'    'device3'    [ 3]
        '3'    'device4'    [34]
    

    Again, the drawback of this is that the last statement will convert all non-cell types (e.g. uint8, char, etc.) into doubles. To avoid this possible conversion:

    % after copying cell array data (areCells) as above, but before ~areCells data
    Cn = arrayfun(@(ii)num2cell(allData{ii}),find(~areCells),'uni',0);
    C(:,~areCells) = [Cn{:}];