Create structure from string name / Rename structure from string name

23 views (last 30 days)
I have a function which takes the name of a folder, creates a string, then compiles relevant data from subfolders into one usable structure for data analysis (MALTAB is great!). I'd like to name this structure the same as the original folder, (ex. All_Data_20220412). Dynamic Field Names will not allow me to start a structure with a string, only the field names (as expected from the name). To get around this, my function defines the structure as 'Combined_Data' (a fixed variable name) and saves it as 'All_Data_20220412.mat' at the end of the function. When I load 'All_Data_20220412.mat', the structure loads as 'Combined_Data' rather than the name of the saved filed. This presents problems when loading multiple as they are overwritten. I output ‘Combined_Data’ as the name of the folder manually, but often clear my workspace and would like it have it saved properly. My ideal solution would have the structure name be the same as the folder from which the data originates. Thanks!
function [Combined_Data] = Import_ADMET_Data(Combined_Data)
%Open Folder & Get a list of all files and folders in this folder.
topLevelFolder = uigetdir('\\FileLocation');
files = dir(topLevelFolder);
dirFlags = [files.isdir];
subFolders = files(dirFlags);
subFolderNames = {subFolders(3:end).name};
%Create name of folder (ideal name for structure)
D = regexp(topLevelFolder,'\d{8}','match','once');
DataName = ['All_Data_' num2str(D)];
for i = 1:sum(DataFolders)
%Open specific test folder
subFiles = dir([topLevelFolder '\' subFolderNames{i}]);
subDirFlags = [subFiles.isdir];
sub2xFolders = subFiles(subDirFlags);
sub2xFolderNames = {sub2xFolders(3:end).name};
%Open All Data Folder
All_DataFiles = dir([topLevelFolder '\' subFolderNames{i} '\All Data']);
dinfo = All_DataFiles(3:end);
[Data_All, info] = All_Data(dinfo);
Combined_Data.(subFolderNames{i}).All_Data = Data_All; %UNABLE TO USE IDEAL STRUCTURE NAME, USED STATIC NAME (Combined_Data) INSTEAD
Combined_Data.(subFolderNames{i}).info = info;
%Open Peak Data Folder
Peak_DataFiles = dir([topLevelFolder '\' subFolderNames{i} '\Peak Data']);
dinfo = Peak_DataFiles(3:end);
[Data_MaxMin, Peaks_MaxMin] = MaxMin_Data(dinfo);
Combined_Data.(subFolderNames{i}).Peak_Data = Data_MaxMin;
Combined_Data.(subFolderNames{i}).Peaks = Peaks_MaxMin;
end
FullFileName = fullfile(topLevelFolder,[DataName '.mat']);
save(FullFileName,'Combined_Data');
end
  2 Comments
dpb
dpb on 13 May 2022
". My ideal solution would have the structure name be the same as the folder..."
That seems superficially OK, but is a really, really bad idea -- using such a name leads to obuscated, slow-to-execute code that is terribly difficult to debug.
Use a static root name; most of your issues would be solved if you turned the script into a function with its own workspace; you can then load data from whatever source generically and not care what the file names are.
Stephen23
Stephen23 on 13 May 2022
Edited: Stephen23 on 13 May 2022
"the structure loads as 'Combined_Data'"
Which is a good thing.
Although you could fiddle around with changing field names as Steven Lord showed you, in fact the simplest and most efficient approach would be to store that meta-data in a variable, not in field/variable names. Writing simpler, more efficient, much more robust code is easy when the variable names are exactly the same in every MAT file.
"This presents problems when loading multiple as they are overwritten."
That would not be a problem if you LOAD into an output variable and use indexing to store the imported data.
And of course treat meta-data (such as foldernames, dates, etc) as data. Because meta-data is data.

Sign in to comment.

Accepted Answer

Steven Lord
Steven Lord on 13 May 2022
Use a fixed name for your struct and user-specified names for the fields, then when you save it use the -struct option. Let's get a temporary file name.
tempFileName = tempname
tempFileName = '/tmp/tp4488d37f_7e3b_494b_a63a_1be307a85306'
Build a struct array with two fields, one with a hard-coded name and one with a name that is stored in a variable.
s = struct('abc', 1);
theFieldName = 'FuSoYa'; % From the video game Final Fantasy 4
s.(theFieldName) = 42
s = struct with fields:
abc: 1 FuSoYa: 42
Call save with the '-struct' option to turn all the fields in the struct into standalone variables in the MAT-file.
save(tempFileName, '-struct', 's')
Check that the MAT-file contains variables whose names are the field names from the struct rather than containing the struct as one variable. The variable s does not appear in the file at all.
whos('-file', tempFileName)
Name Size Bytes Class Attributes FuSoYa 1x1 8 double abc 1x1 8 double
Let's recreate s.
s2 = load(tempFileName)
s2 = struct with fields:
abc: 1 FuSoYa: 42
check = isequal(s, s2) % true
check = logical
1

More Answers (0)

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!