Seeking a little clarification on using sprintf with %d and formatSpec etc. to load similar *.MAT filenames that only differ in name by number.

Hi,
I have previously written code to successfully load multiple *.MAT files from the directory that were named "Position01.mat ... Position10.mat" using ..
NumFiles = 10;
AudioCell = cell(2, NumFiles);
for k = 1: NumFiles;
Position = sprintf('Position%02d.mat', k);
AudioCell{1,k} = importdata(Position);
AudioCell{2,k} = Position;
end
I want to do the same for a group of files named "Band200Hz.mat", "Band400Hz.mat" ... by octave band to ... "Band12000Hz.mat" and I've tried to specify the filename format in a few different ways, but not been able to find the symbol(s) that works. The documentation on format specifiers isn't necessarly too clear or easy to understand for me. I think the biggest complication I (think I) face is that there isn't a ocnsistent number of different digits in each file; i.e., some have 3, like 'Band400Hz.mat' up to five as with 'Band20000Hz', so can't specify in a similar way to the first example by simply adding 'Hz' to the end, after the number specifier. Thusly ...
NumBands = 8;
MasterCell = cell(2, NumBands);
for k = 1 : NumBands
Band = sprintf('Band%02dHz.mat', k);
MasterCell{1,k} = importdata(Band);
MasterCell{2,k} = Band;
end
A "brute force" workaround would be to put the octave band filtered signal *.MAT files into their own directory and use ...
dir('*.mat')
But I'd prefer to avoid that.
Any help or helpful links regarding this kind of format specification would be greatly appreciated. If there are any entirely different approaches, I'm interested to find out about those too. Thanks a lot!

 Risposta accettata

Less brute
sad = dir( fullfile( root_folder, '**', 'Band*Hz.mat') );
However, this assumes that you want to read all files under the root, which matches the pattern.
Or your approach
for k = 1 : [ 2.^[1:8]*100] % by octave band
sprintf('Band%dHz.mat', k);
...
'Band20000Hz' is not in my sequence, but should it be?
Then I would use load() rather than importdata() (?)
EDIT:
With names like "Band3150Hz.mat" and "Band20000Hz.mat" use
for k = 1 : [200,400,..,3150,20000]

4 Commenti

In general it is better to loop over indices (as the original question does) rather than over data values. Then the indices can be used directly to index into any arrays, vectors, etc.
Also note that this
for k = 1 : [200,400,..,3150,20000]
is exactly equivalent to
for k = 1 : 200
as for non-scalar input arguments the colon operator only considers the first element.
The first suggesting looks appealing, and the files are in the same root directory. I hadn't read that star substitution could be used like that.
Band20000Hz.mat is in the sequence. I will try 'load' and see how that goes. Though, I am more or less compying a wonderfully functioning script I've already written, it's just the difference in name format that I want to overcome, and Stephen said it was even simpler than that last script. I'm probably overthinking this.
So I gave this a try ...
for k = 1 : [200,400,800,1600,3150,6300,12500,20000]
Band = sprintf('Band%dHz.mat', k);
MasterCell{1,k} = importdata(Band);
MasterCell{2,k} = Band;
end
As I tried above, putting the frequencies into the 'for' loop as your edit showed looks like a neat solution, but was unable to load any files. Have I made an obvious mistake and/or missed something silly? But really I'd like to load each file into a cell with its name in the row below, like I've done in previous scripts; which I believe is the better option.
Thanks for your help so far :)
Maybe, we should honor Stephen's advice
k = [200,400,800,1600,3150,6300,12500,20000];
MasterCell = cell(2,numel(k));
for jj = 1 : numel(k)
Band = sprintf('Band%dHz.mat', k(jj));
MasterCell{1,jj} = importdata(Band);
MasterCell{2,jj} = Band;
end
This script must be run in the folder of the mat-files.
"but was unable to load any files" What happend, any error message? Hard for us to guess!
"obvious mistake" Your script will create a huge cell array, MasterCell, with the size 2x20000. That counts as a mistake.
The error was just that: "Unable to load file" when it got to the first four-digit value.
Thanks for your help.

Accedi per commentare.

Più risposte (1)

you can use:
sprintf('Band%dHz.mat', k*200);

6 Commenti

Thanks very much for your answer. Unfortunately, that only works with frequency bands of three digits, So, that will load and import "Band200Hz.mat" and "Band400Hz.mat" but none of the others with 4 and 5 digit frequency labels like "Band3150Hz.mat" and "Band20000Hz.mat" (I hope I'm being clear enough in how the files are named). So I need it to call files with three, four and five digits between 'Band' and 'Hz'. I've got it figured out if the numbers in the filename are the same length ... but becaue they're different, I think it makes it much trickier.
"I hope I'm being clear enough in how the files are named" I for one doesn't get it.
Sorry. The eight *.MAT files are:
"Band200Hz.mat", "Band400Hz.mat", "Band800Hz.mat", "Band1600Hz.mat", "Band3150Hz.mat". "Band6300Hz.mat" and "Band12000Hz.mat" ...
I used Asad Khoddam's answer this way and it returned the following (attached screenshot) ...
NumBands = 8;
MasterCell = cell(2, NumBands);
for k = 1 : NumBands
Band = sprintf('Band%dHz.mat', k*200);
MasterCell{1,k} = importdata(Band);
MasterCell{2,k} = Band;
end
Which is why I thought it was only applying to 3 digit labels. And that k * 200 was doing it with 1 * 200 = 200, 2 * 200 = 400, then there's no file name with 600 in it, no 'Band600Hz.mat', so there the 'for' loop stopped.
I'm sorry if I don't understand it all completely, be assured I'm trying my hardest.
Add the line
assert( isfile(Band), 'Cannot find: "%s"', Band )
before importdata().
Exactly, no integer * 200 will equal 3150, so that's what made me think multiplying k by 200 wouldn't work. Why is that logic flawed? And it didn't work, as soon as it went looking for "Band600Hz.mat", it returned the error "Unable to load file".
Please to see that you're editing insults out of your comments ... you'll get to the level of "civility" soon enough.
Thanks for your help!

Accedi per commentare.

Prodotti

Release

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by