Locating characters in a string array

Hi,
I've generated a list of numerous characters in a string (102) and assigned each character a number (1:102) in the second column to form a 102x2 string array.
What I want to do is seach for a character (column 1) and obtain the number it is assigned (column 2).
Causing me some headaches - thanks in advance!

Answers (3)

dpb
dpb on 28 Jun 2020
As the other respondent says, you don't need a corollary array unless the lookup isn't 1:1 with position (which your description implies it isn't).
The builtin functions for the purpose are strfind and contains for simple pattern matching; there's regexp for regular expressions.
See the documentation for strings, cell strings and character string arrays in the section of "Data Types" in the documentation for complete discussion of the varied ways to deal with text data in MATLAB.
In first step you are creating a string whose length is 102.
In second step you are creating a array of 1:102. But, in a string each character has its own index value. i.e first character index=1 and last character index=102. So, there is no need to create a another column to find corresponding number.
we can find the answer with the following example code.
x = 'Scott Dean Seedell'
y = find(x=='S')
answer will be: y = 1 12
i.e. corresponding numbers of character 'S' are 1 and 12.

15 Comments

Much appreciated, thank you.
dpb
dpb on 28 Jun 2020
Edited: dpb on 29 Jun 2020
>> x = 'Scott Dean Seedell';
>> strfind(x,'S')
ans =
1 12
>>
Is the assigned number you gave it just it's index (location) in the character array, or is it some independent number unrelated to its index?
Hi, further thought on this...
If I have a 100x4 string and want to search for a character, then print the values in the same row as the character, how best can I carry this out? For instance, if I want to search for a character in column 4, row 10 - how could I then obtain the values in columns 1:3 of row 10?
Thanks
Show more detail of your actual use case -- including the precise storage using.
Hi,
So what I'm trying to do is generate a list of all the lines and their connected buses in a distribution system (using external software - OpenDSS):
% Generate all lines and their connected buses
for i = 1:max(size(Line_list));
DSSText.Command = ['? Line.',Line_list{Sel_line},'.Bus1'];
K = DSSCktElement.BusNames;
NumK = numel(K);
K2 = (1:NumK)';
LineBus_Char_Num = zeros(NumK,2);
LineBus_Char_Num = [ K2 convertCharsToStrings(K)];
Bus1 = LineBus_Char_Num(1,2);
Bus2 = LineBus_Char_Num(2,2);
Line_bus (i,1) = Bus1;
Line_bus (i,2) = Bus2;
Line_bus (i,3) = Sel_line;
Sel_line = Sel_line + 1;
end
% Add line names to Line_bus (column 4)
Line_bus (:,4) = string(Line_list);
At the end of this I have a 4 column string array and I want to be able to search for the name of any given bus and ascertain which lines are connected to it by checking the same row as the bus name and obtaining the characters. The names of the buses and lines are sometimes integers and sometimes characters. Thanks
That looks awfully complicated -- can you provide a copy of (I guess it would be variable K that you're building this array out of?
Is DSSText.Command a property or what? It doesn't seem it has much connection to anything else...unless the .BusNames method(?) uses it behind the scenes, mayhaps???
As noted before, sample data and small demos are the best way to illustrate -- so folks don't have to try to make up something to play with (and that may after the effort, not reflect the real problem).
"MAKE IT EASY FOR US TO HELP YOU!!!!
Thanks for coming back to me and sorry for not making it clearer. I've only been playing with Matlab seriously for a few months and asking for assistance on here isn't someting I've done previously.
Appreciate that section will not look perfect, there are some bits that could be tidied. Some of the code will relate to the commands for 'Open DSS' which in this case is being controlled within matlab. Correct, K is a 2x1 cell array which holds the bus names for a given line (generated with the 'DSSText.Command' section and then for each new line incremented with i after each iteration of the for loop). Some bus names may be integers and some may be characters. 'Line_list' is in this case a 100x1 cell array of all the line names. Essentially it ends up with a 4x column string array of Bus 1, Bus 2, Selected line and line name. Hopefully you can see what I mean, but essentially I need to cross-reference the bus names with the corresponding line name within each row.
The bigger picture in the code is a monte carlo loop randomly selecting a location (bus) for a generator and I need to make sure the lines connected to the bus are not overloaded.
Any assistance would be gratefully received, if I have to rehash things a bit to get it working then so be it.
Thanks
As noted before, sample data and small demos are the best way to illustrate -- so folks don't have to try to make up something to play with (and that may after the effort, not reflect the real problem).
"MAKE IT EASY FOR US TO HELP YOU!!!!
Not really sure what more I can give you.
All I wanted was for someone to offer advice how I can search for a character in a string array and obtain the information from the rest of the row. Thanks anyway.
A set of the data you have as you have it is all we need...use paperclip and attach a file or just cut and paste some text...
A start would be
save seedall Line_list K line_bus
will leave you a file 'seedall.mat" with the content of those variables. Attach it (use paperclip icon) and then we can see EXACTLY what you're looking at instead of continuing to guess.
BTW, at least part of the reason for wanting to see acutal data is that I strongly suspect you should turn many (if not all) of these into categorical() variables instead of strings; much simplifying the searching.
Sorry, I didn't know that was possible.
Does the attached make it possible to see better?
Thanks
Well, let me go look and see...I'm sure it will. Storm last night took out the line (wind broke off a dead limb that had been intending to get down) that feeds the well so have to get finished putting it all back first...

Sign in to comment.

OK, got the electrical problem in stable state for time being with power back the main well so cattle are drinking...shop not on but can live without the old shop temporarily...
Anyway, I'd do something like this with your Line_Bus array but wonder why there's so much duplicated and seemingly just sequentially-numbered data. Seems like a lot of redundancy in the duplicated data department of redundancy department, but maybe this is just demo data??? That aside--
Line_bus=categorical(Line_bus); % make them all categorical() arrays
fnLocateLine=@(l) find(Line_busC(:,4)==l); % define a lookup function for shorthand
% Illustrate using lookup...
>> ix=fnLocateLine('line10') % return index of given location
ix =
9
>> Line_busC(fnLocateLine('line10'),:) % return the data associated with the index...
ans =
1×4 categorical array
8 9 9 line10
>>
It possibly could be more useful to leave the numeric columns as numeric but if they're just IDs, the categorical is probably better than string.

10 Comments

You're a star, thank you...I'll have a play.
Incidentallly I hope you resolve your electrical problems soon!
Glad to help...what I wasn't able to decipher before was that you really didn't need a search within a string but just for a string.
BTW, if for some reason there's a real reason to use the data as string instead of categorical owing to processing later in some manner, you can use contains the same was as above to return a logical array which can turn into index via find.
SIDEBAR:
Turns out the old panel box (and we're talking I don't have any idea how old, but back in the days of cloth-insulated wire) apparently also gave up the ghost and was shorting across its main so I couldn't turn power back on to the shop. Debugging symptoms today revealed that in the end...so, I've now got a new breaker box in and wire pulled--it does provide power in again w/o the feed breaker tripping so that fault has been removed. I'll go put the breakers in and wire up the inside circuits here in a little while -- that will let me do them one-by-one, though, if there any faults have sprung up inside with having handled that old wire...not exactly what had planned for this week!!!
Hi, I hope you got your electrics sorted...
Just a quick one (hopefully), I've taken your example and changed it a bit to suit my code:
% make Line_bus a categorical() array
Line_bus=categorical(Line_bus);
% define a lookup function for shorthand
fnLocateLine=@(l) find(Line_bus(:,1)==l);
% return index of given location
ix=fnLocateLine(Assigned_Bus);
% return the data associated with the index.
Line_Bus_Find = Line_bus(fnLocateLine(Assigned_Bus)),:);
% return connected lines from Assigned_Bus
Assigned_Bus_connected_lines(1,1) = Line_Bus_Find(1,4);
It gets stuck on line 4 sometimes and I suspect it may that because the variable (Assigned_Bus) is sometimes an integer and sometimes a character. When I try this manually it seems to get stuck on characters.
It's randomly selecting Assigned_Bus with this previous section:
Assigned_Bus = char(Buses(randi([1 numel(Buses)])));
I've attached Buses and Line_Bus if it helps...
Thanks
Works for me...not sure what your use case was/is that causes a problem.
You did remember to either use a try...catch construct or test for an empty result if the match fails because you've asked for a non-present category, correct? In that case you get an empty result which would fail on a subsequent attempt to use as an array index.
Post an actual failure example with accompanying error messge if that isn't the problem...
Me again.
The error message is attached as a pdf...any idea?
Would need a small sample test case that can reproduce the problem...can't tell anything about root cause just from the message.
It's tell you the reference is out of bounds, though, which means the array is zero-length since the row index is hardcoded as 1.
That would tend to go along with the above of an empty lookup operation.
Hello you.
Well I haven't done much lately on this problem (numerous other issues to worry about).
Needless to say the above issue still remains (funny enough it hasn't fixed itself).
If you're feeing helpful, can you let me know what you may need to diagnose it?
Cheers
dpb
dpb on 26 Oct 2020
Edited: dpb on 27 Oct 2020
As above, a sample test case that reproduces the issue...code and data to run it that creates the error.
I see in looking at the past conversation I said that what it was you provided before had worked for me...so that's what left me hanging--I couldn't reproduce the error with the data/code I had at hand so couldn't diagnose what was/is going wrong at your end.
So, what we need is a complete test case of code and data that produces the error so can catch it in the act...
I managed to resolve it (was actually quite simple in the end, I was looking for something that wasn't there).
As you're rather helpful though, I'm having some difficulty plotting a surface with the results. I've attached 'C' from which I'm trying to obtain a 3D surface plot with column 3 as the Z axis and 1&2 as X and Y. It's coming out all wrong though - any ideas?
MATLAB surface plots are pretty restrictive -- must have X,Y data in meshgrid form with a corresponding Z 2D matrix; it doesn't have the facilities to handle columnar Z (as you've undoubtedly discovered)
You would have to create a meshgrid and fill in with interpolation to use those; however, you can visualize the data with scatter3 which will accept the vector form--doing that for your data results in:
There's really no evidence of any surface at all, anyway -- I then followed up with the marginal plots of Z vs X and Y alone and they also are basically random with only a slight preponderance to more values centered around Z=3E4 than higher, but still there's no indication of any real pattern that a surface would fit.

Sign in to comment.

Categories

Asked:

on 28 Jun 2020

Commented:

dpb
on 11 Nov 2020

Community Treasure Hunt

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

Start Hunting!