MATLAB: Help preallocating variables for a table

MATLABpreallocatetable

Hi everyone,
so i have written some code which goes like this:
function caTable = makeCaTable(caCM)
% creates a table with information about the frames(coordinates of the
% centroids and the total number of cells in the frame)
Frame = {};
PosX = {};
PosY = {};
NumberOfCells = {};
for i = 1:size(caCM,2)
C = chop(caCM{1,i},0);
for j = 1:size(C,1)
Frame{end+1,1} = i;
PosX{end+1,1} = C(j,1);
PosY{end+1,1} = C(j,2);
if(j == 1)
NumberOfCells{end+1,1} = size(C,1);
else
NumberOfCells{end+1,1} = '-';
end
end
end
% write the table
caTable = table(Frame, PosX, PosY, NumberOfCells);
it works and gives me the results i want. But now i want to preallocate the variables. I thought I do it like this:
[nrows,ncols] = cellfun(@size,caCM);
rows = sum(nrows);
Frames = cell(rows,1);
PosX = cell(rows,1);
PosY = cell(rows,1);
NumberOfObjects = cell(rows,1);
But if i do so i cant use my for loop the way i wrote it, since it would always put the values at the end of the preallocated matrices. But if i simply use:
Frames(j,1) = i
my table will not have all the fields. I really don't know how i can fix this. Maybe some of you could help me with that.
Thank you very much!

Best Answer

C is a matrix with doubles in it
In that case,
function caTable = makeCaTable(caCM)
%doc goes here
% caCM: a 2D(?) cell array
% caTable:a table with 4 variables: Frame, PosX, PosY, NumberOfCells
chopped = cellfun(@(x) chop(x, 0), caCM(1, :), 'UniformOutput', false)'; %transpose for easier repelem and cell2mat
NumberOfCells = cellfun(@(m) size(m, 1), chopped);
NumberOfCells = repelem(NumberOfCells , NumberOfCells );
Frame = repelem((1:size(chopped, 1))', NumberOfCells);
chopped = cell2mat(chopped);
PosX = chopped(:, 1);
PosY = chopped(:, 2);
caTable = table(Frame, PosX, posY, NumberOfCells);
end
As a rule you shouldn't be using cell arrays unless you need to, they're slower to process and takes a lot more memory than a matrix (15 times more if each cell is just a scalar double).
Note that I'm replicating the number of cells for all rows of a frame instead of having '-' for all rows but the first of the frame. It's rarely a good idea to mix numbers and characters in a variable. If you want a different value for all but the first row, I'd recommend using NaN instead. It's trivially done:
NumberOfCells = repelem(NumberOfCells, NumberOfCells); %continuing on from there
NumberOfCells([false; diff(NumberOfCells) == 0]) = NaN;
If you really want a '-', then it's slightly more complicated:
ncells = repelem(NumberOfCells, NumberOfCells);
NumberOfCells = num2cell(ncells);
NumberOfCells([false; diff(NumberOfCells) == 0]) = {'-'};