How can I change variable names in a for loop?

15 views (last 30 days)
Hi,
I have exported some simulation results from another software to MATLAB. Now I have 27 variables with names such as vN1a,vN2a....vN27a. I am trying to get max value of each variable using for loop. The problem is I don't know how I can change the numbers in the names of my variables. Some people use eval function, but here the case is a bit different.
Here is my code
clc,clear
format short g
v_max = zeros(27,1);
load('Filename.MAT');
for x=1:1:27
v_max(x,1) = v_max(x,1) + max(vN1a); % I tried max(vNxa), but it didn't work at all.
end
v_max
any suggestions?
  5 Comments
Stephen23
Stephen23 on 27 Jan 2016
Edited: Stephen23 on 27 Jan 2016
@the cyclist: I have already resolved both of these "issues" in my comments to your answer. Briefly:
  1. the fieldnames were specified using sprintf, thus only the desired fields were chosen.
  2. the fieldnames are generated in a loop, and the loop variable can be chosen to be in any order.
This neatly resolves both of these "issues". It should be noted that you also used sprintf in your Answer, to achieve exactly these aims (specific variables & sequence), but with slow, buggy eval instead of fast and neat fieldnames. There is absolutely no "trickiness" involved, just some fast, simple, reliable code without using eval.
the cyclist
the cyclist on 27 Jan 2016
Oh, sweet! Sorry for the redundant comment because I missed that.

Sign in to comment.

Accepted Answer

the cyclist
the cyclist on 27 Jan 2016
Edited: the cyclist on 27 Jan 2016
You can find words of wisdom all over this forum about why it is a terrible idea to names variables a1, a2, a3, etc.
However, if your hands are absolutely tied, and you have no choice but to work with such variable names (because of an outside program that you had no control over), then eval might be your only option.
In your case, I think the following line does what you want:
eval(['v_max(x,1) = v_max(x,1) + max(vN',sprintf('%d',x),'a)'])
Note that what I did there was to split up the string to be evaluated into parts, and then used sprintf to convert the numerical variable x, and insert it into the string where needed.
  7 Comments
Stephen23
Stephen23 on 27 Jan 2016
Edited: Stephen23 on 27 Jan 2016
You can loop over the fieldnames using exactly the same tools you used to generate the eval strings, such as sprintf, because the fieldnames are also strings. sprintf is what the cyclist used in their answer, so why not try it here too?
I do not have your data, but this example should make it clear (with 'a', 'b', and 'c' fieldnames):
% structure, like from S = load(..)
S.vN1a = 1:3;
S.vN2a = 2:4;
S.vN3a = 3:5;
S.vN1b = Inf;
S.vN1c = NaN;
S.vN2b = Inf;
S.vN3b = Inf;
% loop over the 'a' fields:
for k = 1:3
fld = sprintf('vN%da',k)
S.(fld)
end
which displays the fieldnames and field values for the three fields with names ending with 'a', in the order determined by the for-loop (the order of the fields in the structure is not important here):
fld = vN1a
ans =
1 2 3
fld = vN2a
ans =
2 3 4
fld = vN3a
ans =
3 4 5
It printed exactly the data that we wanted (from the three 'a' fields), and none of the other data! Hurrah! You easily choose which fields you wish to work with, because you can either:
  • define the fieldnames yourself (like this example)
  • get the fieldnames from the structure and filter them
Both of these methods are neat, fast, secure, clear code, and simple to debug. Why do beginners love using slow, buggy, obfuscated, and insecure eval?
"I'm sorry Stephen I'm not convinced by your arguments." they are not my arguments. I did not invent the idea that eval is a stupid way to write code: I just read a lot of information, and learned why this is true.
Khalid Khawaja
Khalid Khawaja on 27 Jan 2016
Great. It's working without any problems. I've got your point now. Thanks for all the trouble you've taken to make things easier for me.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 27 Jan 2016
Vs = {vN1a,vN2a....vN27a};
Now you can loop
for K = 1 : length(Vs)
vmax(K) = max(Vs{K});
end
  1 Comment
Khalid Khawaja
Khalid Khawaja on 27 Jan 2016
The question arises how I can create Vs = {vN1a,vN2a....vN27a}; using a for loop if .MAT file has vN1a, vN2a......vN1000a,iN1a, iN2a......iN1000a.

Sign in to comment.

Categories

Find more on Structures 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!