loop over struct with multiple functions

1 view (last 30 days)
Tim Dreßler
Tim Dreßler on 10 Nov 2022
Commented: Tim Dreßler on 10 Nov 2022
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 Comments
Jiri Hajek
Jiri Hajek on 10 Nov 2022
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...
Tim Dreßler
Tim Dreßler on 10 Nov 2022
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!

Sign in to comment.

Answers (0)

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!