How to access variables with incremental names using for loop index?

46 views (last 30 days)
I want to change code such as this
limb_ph1_avg=mean(limb_ph1);
limb_ph2_avg=mean(limb_ph2);
limb_ph3_avg=mean(limb_ph3);
into something using a for loop like
for ii=1:3
limb_ph(somehow insert index count)_avg=mean(limb_ph(insert index count again);
end
All of the variables I am averaging are already in the workspace. I want to be able to accomplish this because 1)I have 24 trials right now, which could change 2)I have many functions that I write on 24 different lines that follow a similar protocol and if I want to change/insert an output/input, I have to edit all 24 lines.
I have tried using sprintf(limb_ph%d) in various ways to no avail. I appreciate the help.

Answers (2)

Walter Roberson
Walter Roberson on 24 Mar 2016
  3 Comments
Walter Roberson
Walter Roberson on 24 Mar 2016
Beforehand,
tr = {tr1, tr2, tr3, tr4, .... tr24};
Then
for k = 1 : 24
[LHS{k},RHS{k},LTO{k},RTO{k}]=strides3(tr{k});
end
Ali Raja
Ali Raja on 16 Sep 2019
Hello everyone,
i am trying to achieve what the OP mentioned however I cannot understand the answer.
Could sombeody please elaborate on this solution?

Sign in to comment.


Ced
Ced on 24 Mar 2016
Edited: Ced on 24 Mar 2016
You could use "eval", i.e.
for i = 1:3
eval(sprintf('limb_ph%i_avg=mean(limb_ph%i)',i,i));
end
but eval should be avoided.
Why not use a cell to save them all? I.e. have them as
limb_ph{1}
limb_ph{2}
...
and then you can even use cellfun if you don't want to explicitely write the loop.
limb_ph_avg = cellfun(@mean,limb_ph);
  4 Comments
Ced
Ced on 25 Mar 2016
To your function question: If you have a function that would change depending on the index, there are several ways of doing this. The correct one depends a bit on how different the functions are. eval or feval are always options, but I will list some alternatives I can think of:
a) Save the function handles in a cell too. E.g.
my_fun{1} = @strides1;
my_fun{2} = @strides2;
etc.
I use this often for e.g. hybrid systems, meaning systems which have different dynamics depending on where they are evaluated. I then have a function assigning the current state to an index, and then call the correct dynamics through the cell.
b) have the iteration be a parameter of your function. If the function does the same thing, but just has a small difference depending on an index, I would suggest changing the function itself to
strides(tr,index)
If these ways do not work, then maybe a for loop doesn't make much sense. For loops are intended to repeat the same action for many objects. If that is not the case, then the for loop is probably not the best selection, especially also for readability.
Stephen23
Stephen23 on 25 Mar 2016
Edited: Stephen23 on 25 Mar 2016
"tr1,tr2,etc. already exist in my program (which I suppose I could also change to be part of a cell) so I want to access and write these variables based on which iteration writes them in a for loop. At this point I cannot figure out a way to do that."
When people choose bad program design it means they write buggy programs using bad programming methods. You seem to be trying to avoid doing the one thing that would actually work efficiently: putting your data into one (cell/structure/numeric) array and accessing it using indices.
Computers are only really good at doing one thing: the same task repeatedly, very fast. So when you sit and patiently copy-and-paste lines of code, making small changes to numbered variables, you are actually doing the computer's work for it. Do you also push your car along the road? Whenever you find yourself repeating lines of code then you are doing something wrong. Get the computer to do this task for you: make a loop, use an index, then the computer will repeat the operation one time, or one million times.
This means that instead of this (which is bad program design (it also forces you to use buggy and slow eval to access the variables):
[LHS1,RHS1,LTO1,RTO1]=strides3(tr1);
[LHS2,RHS2,LTO2,RTO2]=strides3(tr2);
[LHS3,RHS3,LTO3,RTO3]=strides3(tr3);
[LHS4,RHS4,LTO4,RTO4]=strides3(tr4);
[LHS5,RHS5,LTO5,RTO5]=strides3(tr5);
... etc
you should be doing this:
TR = [all tr's in a vector];
[LHS,RHS,LTO,RTO] = arrayfun(@strides3, TR, 'Uni',0);
or in a loop if you prefer. Either of these will be much faster and more robust than any of hack code that you will invent to access your separate variables.
"If you want more effective programmers, you will discover that they should not waste their time debugging, they should not introduce the bugs to start with." Edsger W. Dijkstra

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!