searching an array for a value embedded in a string

Probably this is hopelessly simple to solve, but I haven't found the way (being a newbie)
I have a number of large arrays that look like this (a small portion only shown):
I'm trying to find a way to search for and extract the "Pan Scale" value from each array (here, = 2 on line 123, red arrow). This element (Pan Scale) may not always be on line 123, so I can't just search for the 123rd row in all the arrays.
How do I search for the string "Pan Scale" and then how do I extract its value (the number after the equal sign)?
UPDATE: OK, I just found a way to get to the cell in my array (named "C"):
C(strcmpi(C(:,1),'Pan Scale = 2'));
but now, how to extract the value (i.e. here, 2)?

 Respuesta aceptada

Kevin Phung
Kevin Phung el 29 de En. de 2019
Editada: Kevin Phung el 29 de En. de 2019
search = 'Pan Scale';
a = C{contains(C,search)} % if C is your cell array, locate index and access cell.
exp = '\d*'; %all consecutive numeric digits
val = str2num(cell2mat(regexp(a,exp,'match')))
^ you can use the above for your other elements too, like 'LightControl' or 'PinHoleDiameter,' etc.
documentation:
https://www.mathworks.com/help/matlab/ref/regexp.html

10 comentarios

Stephen
Stephen el 29 de En. de 2019
Yes! Thanks x 10e6 Kevin
Stephen
Stephen el 29 de En. de 2019
Kevin, a follow up if you have a moment: "val" returns a string. But I need a number value. Sometimes the number that follows the = sign is 2, sometimes it is 2.300, sometimes it is 23.00. The number of significant digits is not necessarily the same all the time. How can I get "val" to recognize a numeric value and distinguish between 2.300 and 23.00 for example?
Kevin Phung
Kevin Phung el 29 de En. de 2019
Editada: Kevin Phung el 29 de En. de 2019
Hello,
the str2num should have already done the conversion, did you miss it?
By the way, I did not account for decimals in my solution, please change the expression argument in regexp() to:
exp = '\d?\.?\d+';
does this answer your question along with the decimal / sigfig problem?
Kevin, yes. Thanks!
But now another snag...everything was working fine with the one test array I was using, but then I tried to open another. Here's my code for importing the array (pretty straightforward I had thought....it's a txt file):
T=readtable('Info.txt');
C = table2cell(T);
"Info.txt" is a large table of data in 2 columns (but many of the cells in column 2 are empty). I am getting the error msg:
Error using readtable (line 198)
Reading failed at line 1041. All lines of a text file must have the same number of delimiters. Line 1041 has 0 delimiters, while
preceding lines have 1.
Note: readtable detected the following parameters:
'Delimiter', '=', 'HeaderLines', 0, 'ReadVariableNames', false, 'Format', '%q%f'
Here's what is happening in "Info.txt" at line 1041 (I opened "Info.txt" in Excel to look at what was the problem):
Capture.JPG
Can you help me get around this snag? BTW, the info I need is up within the first ~200 rows, so I could import only the first 200 or so rows if I knew how.
hello, it sounds like you just need to stick an equal sign in there, to be consistent with the two column format of your table (because the equal sign is your delimiter here)
I had to do some searching for ya:
from:
T = readtable('patients.xls',...
'Range','C2:E6',...
'ReadVariableNames',false)
let me know if you can read it from an .xls instead of txt, or if you can change the range parameter to 1:100
Kevin, hopefully you're very patient!
OK, I found a solution and can read in my txt table, but now your code is giving me an error:
opts = detectImportOptions('C:\Info.txt');
opts.SelectedVariableNames = {'Var1','Var2'};
T = readtable('Info.txt',opts); % importS the table
C = table2cell(T); % convertS table to an array
search = 'Time Per Frame'; % serch for the entry, Time Per Frame
a = C{contains(C,search)} % locates cell in C and access cell.
exp = '\d?\.?\d+';
Here's what the array C looks like:
Capture1.JPG
Capture2.JPG
I'm trying to find the entry in row 48 (but this row varies from array to array so can't just specify row 48 in my script).
When I walk through the script line by line to isolate the problem, I get this error when I evaluate the next to last line:
a = C{contains(C,search)}
Error using contains (line 40)
First argument must be a string array, character vector, or cell array of character vectors.
Any help on this?
Wait! Update...
This returns the cell that contains the string 'Time Per Frame':
a = C{contains(C(:,1),search)};
Capture.JPG
but it doesn't get me the data in column 2 of that row, i.e. the number
Kevin Phung
Kevin Phung el 30 de En. de 2019
Editada: Kevin Phung el 30 de En. de 2019
I see, that is because in the beginning, the situation was that Pan Scale and its value is in the same cell.
Is this still the same C array as before? Or is Pan Scale and its value 12 in different columns now?
Because if they are the latter (in different columns) like in this case
Column 1: Time Per Frame
Column 2: 98800;
then maybe you can do:
value = C{contains(C(:,1),search),2}
so that it grabs the second column associated with that same row that it found with 'contains(C(:,1),search)'
This may be a more tricky problem if your situation is the former (search term and its value in the same cell), in which case you're going to have to pass some logic for whether it has to look at the second column.
Let me know if you need more clarification or help-- hopefully I wasnt too vague!
Wait again...FINALLY solved this mess myself. Primie example of 100 monkeys given infinite time on computers could generate a Shakespearean sonnet!
FYI:
clc;
[FileName,PathName] = uigetfile('*.txt','Select the txt file'); % select or enter the name of the txt file containing the ImageJ metadata
path=strcat(PathName,FileName); % construct a path for finding this txt file
opts = detectImportOptions(path); % list the options available in this file
opts.SelectedVariableNames = {'Var1','Var2'}; % choose to import only the columns named 'Var1' and 'Var2'
T = readtable(path,opts); % this imports the metadata into table T
C = table2cell(T); % convert table T to array C
search = 'Time Per Frame'; % define the variable, 'search' to = 'Time Per Frame'
a = C{contains(C(:,1),search)}; % C is your cell array; this locates index and access cell.
Index = find(contains(C(:,1),search)); % finds the row containing the string 'Time Per Frame'
val=C(Index,2); % creates the variable, val, = time per frame (number in the second column of that row)
scantime = cell2mat(val)/1000000 % generates variable, 'scantime', equal to value of time per frame (which is in microsec), in sec
Probably kludgey, but works.
woohoo!! You can probably condense a line or two, but that's not too important.
now I can finally sleep at night.

Iniciar sesión para comentar.

Más respuestas (1)

madhan ravi
madhan ravi el 29 de En. de 2019
Editada: madhan ravi el 29 de En. de 2019
The below code can extract the numeric digit/s equated to Pan Scale:
r=cellfun(@(x)regexp(x,'(?<=Pan Scale.{0,10})\d{0,10}\.?\d{0,10}',...
'match'),C,'un',0);
R=cellfun(@str2double,r,'un',0);
Result=vertcat(R{:}) % if you want the result to be a column vector
Result=[R{:}] % if you want the result to be a row vector

1 comentario

Stephen
Stephen el 30 de En. de 2019
Thanks, Ravi. Being a newbie, I'm having a little easier time understanding and following Kevin's script. Nevertheless, I appreciate your help.

Iniciar sesión para comentar.

Categorías

Productos

Preguntada:

el 29 de En. de 2019

Comentada:

el 30 de En. de 2019

Community Treasure Hunt

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

Start Hunting!

Translated by