How do I create a new variable with another variables' value as its name?

12 views (last 30 days)
I need to go through multiple text files and create arrays based on the data in them. However, each variable needs to have it's own name based on the file it's from. So far I've gotten this:
%code to import multiple files at once
files = dir("*.csv");
len = length(files);
for i = 1:len
array_name = sprintf("t%s",files(i).name); %generates the proper file name for array
new_arr = readmatrix(files(i).name, 'Range', 'A3:A25'); %import data from file
%rename new_arr to array_name string here
end
The issue is that each time the function loops, I need the arrays created to take on the array_name value as its variable name (i.e. "new_arr" should be replaced with the value of array_name).
I am aware that dynamic variables are not best practice, but I do need to create a new variable each time. I have tried eval, but it will not accept the string output of array_name and I cannot use struct because the string as a field name appears to be invalid.
  5 Comments
Stephen23
Stephen23 on 9 Feb 2023
Edited: Stephen23 on 9 Feb 2023
"in the second program, I can only access the data through visual inspection of variable names"
My heartfelt sympathy on having to work with such a tool. Hopefully you can see where things could be done better, should you ever need to implement something like that youself. Good luck!
You will need to keep in mind that naming variables after filenames is very fragile: many/most characters that are valid in filenames are not valid in MATLAB variable names, so in general you would need to convert/remove such characters to something valid. This then causes collisions, where different filenames convert to the same variable name... you can fiddle around with tools like GENVARNAME(), but ultimately there is no trivial solution to this.

Sign in to comment.

Accepted Answer

Dinesh
Dinesh on 9 Feb 2023
Edited: Dinesh on 9 Feb 2023
Hi Nithila,
I believe that the mistake is because of incorrect usage of "eval". The following code worked for me when I was trying to use "eval" in your case:
files = dir("*.csv");
len = length(files);
for i = 1:len
array_name = sprintf('t%s',files(i).name);
eval([array_name '= readmatrix(files(i).name, "Range", "A3:A25");']);
end
disp(tbos2021ModC); % displaying the dynamically created variable name ("t<file_name>") through a file in my local directory
Output:
As you can see, the variable that was dynamically created has the required data stored in it.
  3 Comments
Walter Roberson
Walter Roberson on 9 Feb 2023
Note that you are not stripping off the file extension .csv when you do the dynamic assignment, so you are going to end up assigning to a field named csv in the target variable.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 9 Feb 2023
There are very few places in MATLAB that require a bare variable name with no possibility of any kind of indexing. The ones that I can come up with at the moment are:
  • for and parfor loop index variable name
  • names of functions in function definitions
  • names of input and output variables in function definitions
  • name of exception object in catch statement
  • parameter names in parameter validation blocks
  • names of variables to save in save() calls, and names of variables to load in load() calls
If you need to generate any of those dynamically (other than load/save) then you are quite likely Doing The Wrong Thing. (there are workarounds for load/save)
If you are not doing any of the above, then you do not need to generate top-level variable names dynamically.
You can create cell arrays of content and have a corresponding name array. Or you can generate dynamic field names for a struct. Or you can define dynamic property names for objects.
  2 Comments
Walter Roberson
Walter Roberson on 9 Feb 2023
global and persistent are good additions to the list.
Fieldnames needing to be plain identifiers is important only in the context of setfield and getfield
That is, it is completely legal to have code such as
body.ankles{2} = 'itchy'
but it is not legal to have code such as
for body.ankles{2} = 1:5
The case of
try
#deliberate error
catch body.ankles{2}
disp(body.ankles)
end
turned out to be an interesting one. The form is not a syntax error -- but if the token immediate after catch is not a bare variable name, then MATLAB treats the situation as-if no name had been given for the exception, with the expression being treated as the first executable statement in the catch block, as if you had written
try
#deliberate error
catch
body.ankles{2}
disp(body.ankles)
end

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!