loop over struct with multiple functions

Dear MATLAB Community,
I have the following problem:
I need to extract 2 specific numbers from pretty large txt files from a specific line. The line(s) is (are) not the same for each txt file. Also in some txt files there is only one line of interest.
I have written the following code to extract the numbers I am interested in from one (manually) entered txt file. In total I have (in the case of a txt file with 2 lines of interest) 4 variables (cal1avg, cal1max, cal2avg, cal2max) which correspond to the 2 numbers per line (4 because there are 2 lines with 2 numbers each). In case of only one line of interst I have set up an if clause that sets the values of the other 2 numbers from the missing line to 0 .
this works, so far so good.
now I want to loop this procedure over many txt files. I imported the txt files into a struct. I want to loop the procedure mentioned over all files from the struct. I further want to add new "collumns" to the struct, one collomn for each variable (cal1avg, cal1max,...).
I tried it without the if function to see if that even works - it does not.
my endproduct should be similar to the following
collumns: filename | cal1avg | cal1max | cal2avg | cal2max (the other collums from the struct don't matter)
here the code for manually entered files (works)
%%extract validation info from one file%%
%enter filename
%note: if you have more (or less) than 2 validations per .txt file you need.
%to adapt the code at the marked spot
text = fileread('001_p2_2021-03-11_11-17-21_Session_Data.txt');
TextAsCells = regexp(text, '\n', 'split');
%search for the line(s) of interest
mask = ~cellfun(@isempty, regexp(TextAsCells, '!CAL VALIDATION HV9 L LEFT'));
line = TextAsCells(mask);
%if there is only one line of interst
if size(line) == [1 1]
cal1 = regexp(line{1,1}, '(-)?\d+(\.\d+)?(e(-|+)\d+)?','match');
%avg is always the 3rd element in the cell
cal1avg = cal1{1,3};
%max is always the 4th element in the cell
cal1max = cal1{1,4};
cal2avg = 0;
cal2max = 0;
%if there are two lines of interest
else if size(line) == [1 2]
cal1 = regexp(line{1,1}, '(-)?\d+(\.\d+)?(e(-|+)\d+)?','match');
cal2 = regexp(line{1,2}, '(-)?\d+(\.\d+)?(e(-|+)\d+)?','match');
cal1avg = cal1{1,3};
cal1max = cal1{1,4};
cal2avg = cal2{1,3};
cal2max = cal2{1,4};
%if something went wrong, i.e. the worng line is chosen
else
disp("error")
end
end
code from the loop I tried to code (does not work) (no error, just nothing happens)
data = dir('*.txt');
for i = 1:length(data)
file = data(i).name;
text = fileread(file);
TextAsCells = regexp(text, '\n', 'split');
mask = ~cellfun(@isempty, regexp(TextAsCells, '!CAL VALIDATION HV9 L LEFT'));
line = TextAsCells(mask);
cal1 = regexp(line{1,1}, '(-)?\d+(\.\d+)?(e(-|+)\d+)?','match');
cal2 = regexp(line{1,2}, '(-)?\d+(\.\d+)?(e(-|+)\d+)?','match');
data(i).cal1avg = cal1{1,3};
data(i).cal1max = cal1{1,4};
data(i).cal2avg = cal2{1,3};
data(i).cal2max = cal2{1,4};
end
I can't share the txt file(s) because they include personal data from the experiment (btw these are eye-tracker data). The files contain text and numbers and they are pretty random (so no matrix or sth). The goal is to show the 4 values (cal1avg, cal1max, ...) for each filename.
Help would be awesome!
Thank you very much!
Best,
Tim

5 Commenti

does your call to "dir" return results?
also you may want to look into the "table" data type
Yes my dir() give me all the files in the directory in a struct (see screenshot). Also note the in the screenshot I only imported 10 files as a test (there are over 400 .txt files in total).
With the screenshot I can also make clear where I want the 4 variables (cal1avg, ...) to be (see screenshot).
It would be also fine if the data is written in a (new) table. The main goal is to have filename and cal1avg, cal1max, cal2avg and cal2max in one file/structure/table with the variables obviuously corresponding to the file they came from.
If that loops runs then the fields CAL1AVG etc. should be defined, but I don't see them in your screenshot. Some ideas for debugging this:
  • check the loop counter: what value does it have?
  • check the values of MASK and LINE (you should change this name to avoid masking the inbuilt LINE function).
  • check the content of the files: do they really contain that text?
Note that you can use READLINES and CONTAINS to simplify your code. Also note that
else if
should be
elseif
Hi, it's really difficult to understand what exactly is your problem. Did you try to debug the code using a breakpoint and stepping through the individual commands? Please tell us, which line of your code does not produce the desired result...
Hey, thank you for all your help. I figured out what the porblem is and it work now how I want it to.
Thank you for your help!

Accedi per commentare.

Risposte (0)

Categorie

Prodotti

Release

R2022b

Richiesto:

il 10 Nov 2022

Commentato:

il 10 Nov 2022

Community Treasure Hunt

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

Start Hunting!

Translated by