Access varying variable names in loop
Show older comments
Hi,
i set up an 8x19 array with numbers varying from 4 to 152, including zeros. (numbering)
I now want to fill a cell-array with data (currently stored in struct array). These struct arrays are named something_numbering, where the number is one of those from 4 to 152.
I tried the following (which obviously did not work):
for m=1:8
for n=1:19
if numbering ~= 0 %check if 8x19 array with numbers is nonzero
data_vector{m,n} = something_('%03d',numbering(m,n)).something.something;
end
end
end
The problem is to include the varying numbering and to maintain the structure of the numbering array.
To make things more precise let me provide you with a minimal example:
numbering = [1 5 23; 0 7 24; 0 9 0]
% i now want the data-array to be
data_vector = [something_001 something_005 something_023;
0 something_007 something_024;
0 something_009 0]
Happy for any help! Cheers
6 Comments
"The problem is to include the varying numbering and to maintain the structure of the numbering array."
Yes, that is a problem.
"Happy for any help!"
Don't do that:
So far you have not told us the most important information: how did you get all of those structures into the workspace? Most likely you did not sit and write out all of their names by hand, so you must have either imported them or created them by code. That is the best place to fix this bad data design.
For example, instead of LOADing directly into the workspace you should always LOAD into an output variable:
S = load(..);
S is a scalar structure, you can easily and efficiently loop over its fieldnames:
Even better would be to avoid forcing meta-data into variable names or fieldnames: meta-data is data, and should be stored in arrays, not in field/variable names. For example, if that data had been sensibly stored in one array then your task would be easy and efficient using some basic indexing. In contrast, bad data design requires slow, complex code to process it.
Oskar Kilgus
on 27 Jun 2023
Stephen23
on 27 Jun 2023
"It doesnt have to be robust or a beauty of code by any means..."
... and is leading to the difficulties that you are facing.
Note that the code you show does not check the order of FILENAMES against the results returned by DIR: the files returned by DIR could be competely different or in a different order and your code would keep on using the same variable names in the same order. This makes your intent unclear: what are you actually trying to achieve? Posting broken code is nowhere a good as your explaining what you are trying to do (note: this means explaining the situation and goal, not your approach to it https://xyproblem.info/ ). Are you trying to rename files? Are you just trying to process some data (if so, how?).
There are a few other bugs, such as assuming that the first two elements returned by DIR are always dot directory names.
And then there is the EVAL and making things magically appear in the workspace. Best avoided. Makes your life harder.
Oskar Kilgus
on 28 Jun 2023
Edited: Oskar Kilgus
on 28 Jun 2023
"another problem is, that the .mat files are all named with numbers in front so i cant import them directly can i?"
I don't see why that would be a problem, this is very common. I routinely import many thousands of data files which have all kinds of numbers in the filenames. Filenames are rather irrelevant to what you can import.
"My intent is to load all these .mat files in a way, that i can easily access the vectors in the "second layer" of the struct-arrays in, lets say a for loop. This way i can ease my data-analysis (e.g. FFT analysis)"
I strongly recommend to import them into one array. From your description, a non-scalar structure might be a good option. That would make it eas to keep all of the imported data together along with the corresponding filenames, etc.
From the non-scalar structure you can simply loop over the elements, etc, and use convenience syntaxes:
Hopefully all of the structures saved within the MAT files have the same name (simpler, more robust, more efficient to process) and not a different name in each MAT file (... ugh, that would be very... unfortunate).
Hopefully the structure fields also have the same names, then merging them together will be easier.
Please upload some sample MAT files by clicking the paperclip button.
In lieu of that, as far as I can tell you have something like this (structures saved in MAT files):
S = struct('X',1:3,'Y','A'); save test1.mat S
S = struct('X',4:6,'Y','B'); save test2.mat S
S = struct('X',7:9,'Y','C'); save test3.mat S
which is easy to import in a loop:
P = '.'; % absolute/relative path to where the files are saved
S = dir(fullfile(P,'*.mat'));
for k = 1:numel(S)
F = fullfile(P,S(k).name);
D = load(F);
D.S.name = F;
S(k).data = D.S;
end
D = [S.data] % all file data
vertcat(D.X) % all X data in one matrix
{D.name}.' % corresponding filenames
Simplify the data design and you make processing it much easier and more efficient. The name "MATLAB" comes from "MATrix LABoratory". MATLAB is designed so that working with matrices and arrays is the best approach (not splitting up the data into lots of separate variables and making the data harder to work with).
edit: another problem is, that the .mat files are all named with numbers in front so i cant import them directly can i?
If you're calling load on a MAT-file whose name starts with numbers in front that's no problem. If you're calling load to read data from a text file in a format load can handle (created with save -ascii for example) then MATLAB would need to create a variable whose name is a modified version of the text file name that is a valid MATLAB identifier.
cd(tempdir)
x = 1:10;
y = x.^2;
save('123mat.mat', 'x', 'y')
The data was stored as expected in the MAT-file.
whos -file 123mat.mat
Calling load to read it into a struct array works fine.
data = load('123mat.mat')
Calling load without an output argument risks overwriting variables that already exist in the workspace. You might expect z to be [42; 3+4i] in the code below; it's not. [If 123mat.mat had not contained variables named x or y it would have.]
x = 42;
y = 3+4i;
load('123mat.mat')
z = [x; y]
Now let's look at a text file. The data looks like it was written correctly in the file (the format of the numbers is a bit different, but the values are the same as we'll see at the end looking at the variable q.)
save('123mat.txt', '-ascii', 'x', 'y')
type 123mat.txt
If we call load with no outputs MATLAB doesn't create a variable named 123mat in the workspace. It can't since that's not a valid variable name. But it creates something close.
clear all
load 123mat.txt
whos
But if we call load with an output that works fine.
q = load('123mat.txt')
Answers (1)
Hi Oskar,
I can point you towards a simple example and hope you can build from it. Conside the code below:
x = 'hello'; % Dynamic content
myStruct = struct('hello', 'world'); % Struct with a field 'name'
fieldValue = myStruct.(x)
Categories
Find more on Workspace Variables and MAT Files 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!