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

4 ビュー (過去 30 日間)
NA
NA 2020 年 8 月 13 日
コメント済み: hosein Javan 2020 年 8 月 14 日
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 件のコメント
NA
NA 2020 年 8 月 13 日
編集済み: NA 2020 年 8 月 13 日
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 2020 年 8 月 13 日
fullfile() squeezes out empty entries ?
Or perhaps
if isempty(control{anim,exp}); break; end

サインインしてコメントする。

採用された回答

hosein Javan
hosein Javan 2020 年 8 月 13 日
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 件のコメント
NA
NA 2020 年 8 月 14 日
Thank you Hosein, I went with your first suggestion, and much more straight forward. Cheers.
hosein Javan
hosein Javan 2020 年 8 月 14 日
you're welcome./

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

製品


リリース

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by