MATLAB Answers

How to create a for loop that iterates based on a string

63 views (last 30 days)
Amy Hassett
Amy Hassett on 23 Mar 2020 at 10:08
Commented: Amy Hassett on 27 Mar 2020 at 8:11
I want to write a loop in matlab that does the following:
  1. pulls rows from a table based on a string value
  2. assigns that data a variable name based on that string
  3. creates a series of graphs based on that variable.
I have written that code for one string, along with the graphs and so on, but now i would like to automate for other strings in the table but I am really struggling with how to do this.
Attached below is the code that I have after the data has been extracted from the table. You will notice that most of the variables I use are named after the string that I pull, which is important because I need to have these variables available to me for further computation once the loop is complete. How can I do this?
JumpAll = dat(dat.NAME == 'WallJump', :); % Extract "Jump" for all animals
JumpM1 = JumpAll(JumpAll.IDANIMALA == 1, :); % Extract "Jump" for M1
JumpM2 = JumpAll(JumpAll.IDANIMALA == 2, :); % Extract "Jump" for M2
JumpM3 = JumpAll(JumpAll.IDANIMALA == 3, :); % Extract "Jump" for M3
% Calculate frequency tables for "Jump" for all and each mouse
tblJumpAll = tabulate(JumpAll.EventDuration);
tblJumpM1 = tabulate(JumpM1.EventDuration);
tblJumpM2 = tabulate(JumpM2.EventDuration);
tblJumpM3 = tabulate(JumpM3.EventDuration);
% Preparation for data visualisation
% We need to pay our arrays for each mouse so that they all have
% the same number of rows (otherwise they cannot be shown on the
% same graph. To do this, we add rows of "0's" to the end to make
% them all the same size as the biggest array (which is
% tblJumpAll)
tblJumpM1 = padarray(tblJumpM1, (size(tblJumpAll, 1) - size(tblJumpM1, 1)), 'post');
tblJumpM2 = padarray(tblJumpM2, (size(tblJumpAll, 1) - size(tblJumpM2, 1)), 'post');
tblJumpM3 = padarray(tblJumpM3, (size(tblJumpAll, 1) - size(tblJumpM3, 1)), 'post');
tblJumpAll(:,3) = []; % remove the 3rd column, we don't need it (it is percentage)
% Plot subplot on figure 1 with 1 frame events
% Set up figure:
figure('Name', 'Jump w/ and w/o single frame events');
subplot(1,2,1);
hold on;
title('Jump w/ and w/o single frame events');
xlabel('Duration (frames)');
ylabel('Number of events');
bar(tblJumpAll(:,1), [tblJumpAll(:,2),tblJumpM1(:,2),tblJumpM2(:,2),tblJumpM3(:,2)], 1, 'histc'); % Plot the data
ax.DataAspectRatioMode = 'auto';
hold on;

  4 Comments

Show 1 older comment
Amy Hassett
Amy Hassett on 23 Mar 2020 at 10:18
Ah yes, I was just about to edit the question to include this. Here is are the strings, I put them into a cell array:
Behaviours = {"Wall Jump"; "Move Isolated"; "Rear Isolated"; "SAP";
"Stop Isolated"; "Huddling"; "Contact"; "Move in contact"; "nose-rear Contact";
"nose-nose Contact"; "Rear in contact"; "Side by side Contact"; "Side by side Contact; opposite way";
"Stop in contact"; "Approach contact"; "Approach rear"; "Break contact"; "Social escape";
"FollowZone Isolated"; "Approach"; "Group2"; "Group3"; "Train2"; "Train3"; "SeqOGOO";
"SeqOOOG"}
Stephen Cobeldick
Stephen Cobeldick on 26 Mar 2020 at 9:42
"You will notice that most of the variables I use are named after the string that I pull..."
Forcing meta-data into variable names is a sign that you are doing something wrong.
"...which is important because I need to have these variables available to me for further computation once the loop is complete"
It is defintely NOT required to magically name variables in order to access that data after the loop. There are many better ways of doing this, e.g. storing the data and the corresonding meta-data in a cell array using simple and very efficient indexing.
"How can I do this?"
Don't force meta.data into variable names. Accessing variable names is one way that beginners force thmselves into writing slow, complex, obfuscated, buggy code that is hard to debug. Read this to know why:
Usually the best solution is to not split your data up and to simply access it directly from the original array.
If you really must split up the data, then you could store both the data and the corresponding meta-data in a cell array using indexing, or use a structure with dynamic fieldnames: https://www.mathworks.com/help/matlab/matlab_prog/generate-field-names-from-variables.html
Both of these will be more efficient and more robust than messing around with dynamic variable names.
Amy Hassett
Amy Hassett on 27 Mar 2020 at 8:11
Yes, so I read this tutorial, and what I did in response to it was to create a structure, wherein the first field corresponded to the names that I would have wanted my variables to take, and the rest of the fields were the data corresponding to that "name", so to speak.
I think that this worked quite well!

Sign in to comment.

Answers (0)

Sign in to answer this question.