Can I create a code to avoid updating the struct every time I use a different struct?
显示 更早的评论
Hi all, and thanks in advance. I have 1x1 struct files which have 65 fields, some fields contain a single number, and others can be opened up and has about 80 cells worth of data. These are files produced by a piece of research equipment, and the name relates to the time the readings were taken, and are unable to be changed.
Is there a way I can easily extract data from specific fields? In every copy of the file the field names remain the same (i,e, Pressure, Compliance etc). Some of these will be single figures, others will be the ones with cells worth of data.
I have hobbled together something which works, but trust me...its bad, I have no idea what I am doing.
While it kind of works, I have to change the struct name in the code every time I open a new file. Is there a way I can avoid having to update the struct code every time? (180+ times a day).
Thanks in advance.
Matt
22 个评论
KSSV
2018-11-9
Why you have to change struct name? There is no necessity according to my knowledge as of now. How you have the data? In a mat file? Each structure into one file? or all structures in one file?
Stephen23
2018-11-9
@Matthew Wilson: most likely you just need to load your .mat files (if that is what you have, your explanation was not very clear) into an output variable. Then you can easily access its fields.
If you want more help with this then please upload some sample files by clicking the paperclip button.
Matthew Wilson
2018-11-9
编辑:Matthew Wilson
2018-11-9
"These are files produced by a piece of research equipment,..."
"The file is a '.m', a 'MATLAB Code' file if that helps."
Seriously, some special equipment writes code files to store data? Why would anyone do that, when there are plenty of perfectly good data file standard in existence?
Oh well, if this equipment's code really is so badly designed and implemented then so be it. Please upload some example files by clicking the paperclip button. Otherwise we have absolutely no idea how that code is structured, or even if it is a script or a function or a class ...
Matthew Wilson
2018-11-9
编辑:Matthew Wilson
2018-11-10
Walter Roberson
2018-11-10
In the code I posted you would use
filename = 'File_WB3DT_2018_10_12__16_10_32.mat'
and you would change the list of character vectors to include EQUIVALENT_EAR_VOLUME, RESONANCE_FREQUENCY, PEAK_PRESSURE, COMPLIANCE_226_Hz, GRADIENT_226_Hz, PEAK_PRESSURE_226_Hz and so on.
The code I posted creates a struct with just those fields. You could easily put the values into a cell array instead. If the values are all numeric and all the same size you could put them into a numeric array. The disadvantage of the cell array or numeric array is that you have to plan out the order you want the fields in, and since the fields are about quantities that are not just values related in time, it might make more sense to use them from a struct so you can extract by name with clear references instead of code that just has to know which offset corresponds to which value.
Matthew Wilson
2018-11-10
编辑:Matthew Wilson
2018-11-10
Walter Roberson
2018-11-10
Use dir to find the files.
dinfo = dir('FILE*.mat');
filenames = {dinfo.name};
for K =1 :length(dinfo)
filename = filenames{K};
....
end
@Matthew Wilson: the data is not saved in a .m file, when you look at the file you supplied the very first code line is clearly load-ing the data from a .mat file:
saveVarsMat = load('File_WB3DT_2018_10_12__16_10_32.mat');
"Patient data/results seem to be stored within the program I think"
Once the data are load-ed from the .mat file they are stored in MATLAB's memory, just like every other variable in MATLAB's base and function workspaces:
Read this to load the data from a sequence of .mat files:
Matthew Wilson
2018-11-11
编辑:Matthew Wilson
2018-11-11
"Would it make it any easier if it was saved like this?"
It depends on what you mean by "easier". It certainly won't make your code or your processing any simpler, because your either have to loop over filenames or fieldnames, and both of those require about the same amount of code. If the separate .mat files already exist, then I would not bother combining them into one.
" Maybe then the code suggested on this page using .mat would pick up the files too"
What code you referring to? You have received several answers. The code I wrote, tested, and showed in my answer already loads your .mat files, so it is completely unclear what you mean.
" I know the code says to open the .mat but it doesn't pick them up while they're in .m format it seems?"
A .mat file cannot be "in .m format", whatever that means. Your data are saved in .mat files. That is what the code in my answer loads. What do .m files have to do with anything?
If by "but it doesn't pick them up" you mean that the data is not being loaded from the file into MATLAB (your terminology is very vague) then the best solution is to find out why:
- how are you checking if the file data has been loaded?
- are the data files saved in the current directory?
- what does exist return when you try to locate one of the .mat files?
Please show us the exact code that you tried using.
Matthew Wilson
2018-11-11
编辑:Matthew Wilson
2018-11-11
@Matthew Wilson: it means that the dir command did not find any .mat files in the current directory. You can fix this by telling your code which directory to look in:
D = 'path to where your .mat files are saved';
S = dir(fullfile(D,'*.mat'));
for k = 1:numel(S)
F = fullfile(D,S(k).name);
T = load(F);
T = struct2cell(T);
S(k).data = T{1};
end
Note that if no files are found then S will not contain the data field and it will be empty, just as you have. The number of elements in S is simply how many files were matched by dir (empty means no files found). Only when the files are load-ed in the loop is the data field added to the structure.
You can either write the folder D yourself, if you know where the files are saved, or browse to the folder and copy-paste from the path from your OS file browser. It can be an absolute or relative path.
Matthew Wilson
2018-11-11
编辑:Matthew Wilson
2018-11-11
"All the files are the .m format of the very first file I uploaded if that helps."
If that is true then if you look inside every single one of those .m files you will find that they all load some .mat file/s. Those .mat files are where you data are actually saved.
Find those .mat files. Their location is what you need to find out. Where are they on your computer?
Matthew Wilson
2018-11-11
@Matthew Wilson: you have said several times that you use those .m files to load your data. What I am trying to do is show you how to load your data from the .mat files where it is actually saved.
Your question asked "Is there a way I can avoid having to update the struct code every time?", and that is what I showed you in my answer and comments. To make it work you will have to find the folder where those .mat files are saved. They are saved on your computer, not mine. All OS's have search functions, so I am sure that you can locate them.
Matthew Wilson
2018-11-11
Walter Roberson
2018-11-11
That is an executable file that can be used to create data. But it is completely different than the earlier .m you posted which consists of doing a load() of a .mat . The ones that do the load() need the mat files, but the one like you just posted do not.
Matthew Wilson
2018-11-11
编辑:Matthew Wilson
2018-11-11
Matthew Wilson
2018-11-12
"Are these similar to .mat files to work with, just need to modify some of the code? Or quite different."
The .m file you posted earlier is totally unrelated to everything that you have uploaded previously on this thread. Answering a question is very difficult when the information keeps changing.
"Would it be best to start a new question now that I have more of an idea "
You could, but based on your most recent .m file the solution will not be particularly simple or neat. Basically the tool that you are using is very badly written because its author has forced meta-data (the date) into the structure's name. Forcing meta-data into a variable name makes accessing that variable slow, complex, and buggy. Read this to know why:
The best solution would be to fix the tool that you are using. Otherwise you will have to run that file, then magically try to access the variable that it creates:
save('temp.mat','-regexp','File_.*_\d{4}_.*')
T = load('temp.mat');
C = struct2cell(T);
A = C{1};
A.PRESSURE
A.FREQ
A.ABSORBANCE
... etc
I recommend getting the tool fixed. If you upload it here or give us a link we might be able to help with that.
回答(3 个)
Walter Roberson
2018-11-9
datastruct = load(filename) ;
FN = fieldnames(datastruct) ;
selected_data = SelectData(datastruct.(FN{1});
function selected = SelectData(S)
fns = {'Pressure', 'Compliance', 'etc'} ;
for K = 1 :length(fns)
fn = fns{K};
selected.(fn) = S.(fn);
end
If each mat file contains only one variable (but its name changes and you don't know the name in advance) then you could just use struct2cell to get the data of that variable. If there are multiple variables in the .mat file then this method can be modified, but what modifications are most suitable depends on how the variables are named, which you have told us nothing about.
Here is a simple method that will load your .mat file/s (which is actually how your data is saved), without knowing the name of the structure inside the .mat file/s.
One Single File
T = load('WB3DT_2018_10_12__16_10_31.mat');
C = struct2cell(T);
A = C{1};
A.PRESSURE
A.FREQ
A.ABSORBANCE
... etc.
Multiple Files
S = dir('*.mat');
for k = 1:numel(S)
T = load(S(k).name);
C = struct2cell(T);
S(k).data = C{1};
end
And then you can access the imported structure simply like this, e.g. here is the data for the first file:
S(1).data.PRESSURE
S(1).data.FREQ
S(1).data.ABSORBANCE
... etc.
1 个评论
@ Matthew Wilson: now that you have actually uploaded a sample data file, it was easy to test my code. Here are some of the values that it imported:
>> S(1).data.RESONANCE_FREQUENCY
ans = 483
>> S(1).data.PEAK_PRESSURE
ans = -5
>> S(1).data.PRESSURE(:)
ans =
178
178
157
148
136
123
106
90
74
59
45
31
18
5
-5
-16
-27
... lots of rows here
-330
-333
-335
-338
-340
-344
-349
-355
-361
-367
-372
-375
-379
-384
-389
-395
Note how the code in my answer does not use the structure name anywhere (which is exactly what your question said that you wanted to acheive).
Matthew Wilson
2018-11-10
0 个投票
9 个评论
Matthew Wilson
2018-11-10
Either:
- crate a .mat file that has the same properties as the one loaded by your .m file, but using some fake data, and upload that.
- clearly describe how the .mat file, e.g. how many variables it contains, etc. For this you can use whos and simply show us what is displayed.
Matthew Wilson
2018-11-10
@Matthew Wilson: please open that .m file. Look at the first line of code. It looks like this:
saveVarsMat = load('WB3DT_2018_10_12__16_10_31.mat');
That load command imports data from a .mat file into MATLAB. That .mat file is where your data is saved. The .mat file's name is WB3DT_2018_10_12__16_10_31.mat. I asked for that .mat file, or something like it, or a description of it (e.g. using whos). Please provide the requested information.
Matthew Wilson
2018-11-10
Stephen23
2018-11-10
"Hoping this is what you mean :)"
Yes, that is the data file.
Note that my answer shows you how to import and access the data in your .mat files without using the structure name, which is exactly what you asked for in your question: "I have to change the struct name in the code every time I open a new file. Is there a way I can avoid having to update the struct code every time?"
Try the code in my answer. When I tested it, it does what you requested. If you have any questions, please make a comment to my answer.
Matthew Wilson
2018-11-11
Walter Roberson
2018-11-11
If you use the code I posted, adjusting for the fields you want, then afterwards you can use struct2table and then writetable
类别
在 帮助中心 和 File Exchange 中查找有关 Workspace Variables and MAT Files 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!