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

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)

3 Comments

Hey Walter, I was actually reading this exact wiki before posting this question. However, I am wondering if there is a good way to use existing variables, not create them. Based on the wiki I tried something like this:
for k=1:24
tr=sprintf('tr%d',k);
[LHS{k},RHS{k},LTO{k},RTO{k}]=strides3(tr);
end
But the problem is that tr=tr1 except it is just a string and not connected to the variable tr1 that is already in existence. I guess I just need a way to connect those two. I tried genvarname as well.
Beforehand,
tr = {tr1, tr2, tr3, tr4, .... tr24};
Then
for k = 1 : 24
[LHS{k},RHS{k},LTO{k},RTO{k}]=strides3(tr{k});
end
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.

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

Using the cell idea would be an alternative for the question I asked so thanks! However, I am looking for a good way to do it with a for loop and variables of incrementing values so that I can apply it to functions as well.
For another example of the function usage I am talking about:
[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);
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.
This way if I wanted to add an output/input to my strides3.m function I would only have to alter one line in the main program instead of the 24 I have now.
A simple rule: If you start numbering variables, you're doing it wrong.
Computers are very good at performing automated tasks. And here you're doing it yourself, copy pasting the same line, and just renumbering the variables. What if you have hundred datasets, will you copy/paste the same line 100 times.
The proper way of solving your problem is not to create those numbered limb_ph in the first place and have just one variable either a matrix (if all limp_ph are the same size) or a cell array.
It is then trivial to calculate the mean of all the datasets in just one line.
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.
"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

Asked:

on 24 Mar 2016

Commented:

on 16 Sep 2019

Community Treasure Hunt

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

Start Hunting!