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

4 Ansichten (letzte 30 Tage)
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.
  4 Kommentare
NA
NA am 13 Aug. 2020
Bearbeitet: NA am 13 Aug. 2020
I tried your suggestion, it does simplify the code. I have pinpointed another error at this point of the for loop:
...
for exp = 2:lengRow
expFolder2 = [control{anim, exp} '\']; %exp folders
load([directory animFolder1 expFolder2 ... 'tim_trl']) %load tim series
end
...
The code counts the empty character vectors as part of the length of each row in the 'control' array
In other words, MATLAB tries to load [ ] from 'folderA', but since it's an empty char vector, this directory doesn't exist. The same applies with when I use 'NaN', and I think this is the point of my problem.
Is there a way to tell MATLAB to not include [ ] or 'NaN' cells, so that when the code runs, the "correct" number of exp load (per folder).
Walter Roberson
Walter Roberson am 13 Aug. 2020
fullfile() squeezes out empty entries ?
Or perhaps
if isempty(control{anim,exp}); break; end

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

hosein Javan
hosein Javan am 13 Aug. 2020
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
  3 Kommentare
NA
NA am 14 Aug. 2020
Thank you Hosein, I went with your first suggestion, and much more straight forward. Cheers.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange

Produkte


Version

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by