MATLAB: Loading a cell array (string) with different lengths into a for loop

cell arraysfor loopMATLABmatrix

Hi All,
I have a cell array (string), as follows:
control = {...
'folderA', 'exp1', 'exp2' 'exp3'... %folder 1
'folderB' 'exp1', 'exp2' 'exp3' 'exp4' 'exp5'... %folder 2
'folderC' 'exp1', 'exp2' 'exp3' 'exp4'... %folder 3
};
Currently, I am analysing one folder at a time in my for loop. This is quite annoying for a number of reasons (which I won't bore you with here). I would much prefer to load the entire 'control' array and analyse folders 1 – 3 (and their contents) continuously in my for loop. After spending quite a bit of time looking for a solution online, I have come to the understanding that:
(1) I need to concatenate my cell array (bearing in mind that the dimentions must be consistent). Though I would have liked to add 'NaN' padding to make the dimensions of my cell array equal to the max length of the array in a for loop, I was unsuccessful, and opted for an easier solution – adding 'NaN' padding manually:
control = {...
'folderA', 'exp1', 'exp2' 'exp3' 'NaN' 'NaN'... %folder 1
'folderB' 'exp1', 'exp2' 'exp3' 'exp4' 'exp5'... %folder 2
'folderC' 'exp1', 'exp2' 'exp3' 'exp4' 'NaN'... %folder 3
};
(2) I need to find the length of each row (not including NaN), so that I can load data correctly through my for loop:
for ii = 1:size(A)
nNaN = sum(cellfun(@(A) strcmp(A, 'NaN'), A), 2);
lengRow = length(A) - nNaN;
end
I ultimately, did find a solution for this, though I wonder if there is a "better" way of finding the lengths of each row (not including NaN)?
Putting everything together, my code looks like this:
control = {...
'folderA', 'exp1', 'exp2' 'exp3' 'NaN' 'NaN'... %folder 1
'folderB' 'exp1', 'exp2' 'exp3' 'exp4' 'exp5'... %folder 2
'folderC' 'exp1', 'exp2' 'exp3' 'exp4' 'NaN'... %folder 3
};
for ii = 1:size(control)
nNaN = sum(cellfun(@(control) strcmp(control, 'NaN'), control), 2);
lengRow = length(control) - nNaN;
end
dataInd = zeros(244141, 16, 50, 5, 3); %preallocate array

meanLFP = zeros(244141, 16, 50, 5, 3); %preallocate array
for anim = 1:size(control,1)
animFolder1 = [control{anim, 1} '\']; %main folder
for exp = 2:lengRow
expFolder2 = [control{anim, exp} '\']; %exp folders
load([directory animFolder1 expFolder2 ... 'tim_trl']) %load tim series
ind1 = find(tim_trl>=20, 1);
ind2 = find(tim_trl>=30, 1); %10s time frame
for trial = 1:50
load([directory animalFolder1 expFolder2... 'trial' num2str(trial)]) %load data
dataInd(:,:,trial) = data_trl(ind1:ind2,:)*1000; %10s of data
end
meanDataInd = squeeze(mean(dataInd, 3)); %now a 244141 x 16 x 5 x 3 matrix
end
end
So far, the issue that I am facing is (I am sure there is more than one, though I cannot tell at this point):
When I run the for loop, only the data from 'folderA' 'exp1' is saved (or loaded) in the preallocated arrays ('dataInd' and 'meanLFP'). I am unsure why this is, and would appreciate some insight.
I would also appreciate any pointers you may have on improving my written code.
Thank you in advace.

Best Answer

you don't even have to concatenate them to one "control" cell array. I suggest create an array called folder where each element refers to each row that you mentioned, then you can easily refer to them and analyse them:
folder{1} = {'folderA' 'exp1' 'exp2' 'exp3'};
folder{2} = {'folderB' 'exp1' 'exp2' 'exp3' 'exp4' 'exp5'};
folder{3} = {'folderC' 'exp1' 'exp2' 'exp3' 'exp4'};
for i = 1:length(folder)
% analyse folder{i}
end
if you want to concatenate them however use the following:
L = cellfun(@length, folder);
maxlength = max(L)
control = cell(3,6);
control(1,1:L(1)) = folder{1};
control(2,1:L(2)) = folder{2};
control(3,1:L(3)) = folder{3}
control =
'folderA' 'exp1' 'exp2' 'exp3' [] []
'folderB' 'exp1' 'exp2' 'exp3' 'exp4' 'exp5'
'folderC' 'exp1' 'exp2' 'exp3' 'exp4' []
for i = 1:size(control,1)
folder_of_interest = control(1,:);
idx_empty = cellfun(@isempty,folder_of_interest)
folder_of_interest = folder_of_interest(~idx_empty);
% analyze the folder of interest here
end