MATLAB Answers

Using strcmp on multiple strings to get a logical array

238 views (last 30 days)
Marc Cousoulis
Marc Cousoulis on 12 Jan 2017
Edited: James Tursa on 16 Jan 2017
I want to check for the occurrence of 3 possible events in a series of events..
Event = ['a1','b1','a1','c1','b1']';
Check = {'a1','b1','c1'}';
LogA(:,1) = strcmp(Event,Check{1});
LogA(:,2) = strcmp(Event,Check{2});
LogA(:,3) = strcmp(Event,Check{3});
This gives me a 5x3 logical array, but is there a way to do it without calling each column individually? i.e., what if I had 100 strings I wanted to check for and the goal was to have a 5x100 logical array? I don't want to use a "for-loop". I'm assuming there is some matrix way to do this.

  1 Comment

Jan
Jan on 15 Jan 2017
Note:
Event = ['a1','b1','a1','c1','b1']';
is the same as:
Event = ('a1b1a1c1b1').';
Most likely you mean a cell string instead.

Sign in to comment.

Accepted Answer

Kirby Fears
Kirby Fears on 12 Jan 2017
Edited: Kirby Fears on 12 Jan 2017
There's really nothing wrong with a for loop in this case. However, cellfun is probably what you're looking for:
Event = {'a1','b1','a1','c1','b1'}';
Check = {'a1','b1','c1'}';
l = cellfun(@(c)strcmp(c,Event),Check,'UniformOutput',false);
This produces a cell array the size of Check with logical arrays the size of Event.
You can index like this:
l{index1}(index2)

  2 Comments

Stephen Cobeldick
Stephen Cobeldick on 13 Jan 2017
Also simple to convert to a logical array:
>> Event = {'a1','b1','a1','c1','b1'};
>> Check = {'a1','b1','c1'};
>> X = cellfun(@(c)strcmp(c,Event),Check,'UniformOutput',false);
>> vertcat(X{:})
ans =
1 0 1 0 0
0 1 0 0 1
0 0 0 1 0
Jan
Jan on 15 Jan 2017
strcmp does not accept: strcmp(Event, Check.') and this does not work also:
bsxfun(@strcmp, Event, Check.') % ERROR!
What a pity.

Sign in to comment.

More Answers (2)

Guillaume
Guillaume on 13 Jan 2017
Edited: Guillaume on 13 Jan 2017
Another option which may or may not be faster than cellfun(...):
Event = {'a1','b1','a1','c1','b1'}';
Check = {'a1','b1','c1'}';
LogA = false(numel(Event), numel(Check));
[~, loc] = ismember(Event, Check);
LogA(sub2ind(size(LogA), 1:numel(Event), loc.')) = true

  0 Comments

Sign in to comment.


John BG
John BG on 13 Jan 2017
Marc
1.
If all 2nd halves of the strings contained in Event is '1', it is reasonable to ignore the entire column:
Event = ['a1';'b1';'a1';'c1';'b1'];
Event_num=double(Event)
=
97 49
98 49
97 49
99 49
98 49
E=Event_num(:,1)';
E =
97 98 97 99 98
2.
Same applies to Checks
Check = ['a1';'b1';'c1'];
Check_num=double(Check)
=
97 49
98 49
99 49
C=Check_num(:,1)';
C =
97 98 99
3.
Occurence of events are listed in variable occ
[Lie,occ]=ismember(E,C)
Lie =
1 1 1 1 1
occ =
1 2 1 3 2
4.
check
Check(occ)
=
abacb
meaning occ contains the occurrences: a1 b1 a1 c1 b1
if you find these lines useful would you please mark my answer as Accepted Answer?
To any other reader, if you find this answer of any help please click on the thumbs-up vote link,
thanks in advance for time and attention
John BG

  5 Comments

Show 2 older comments
John BG
John BG on 14 Jan 2017
To Marc Cousloulis:
did you mark this question as Accepted Answer or did some one else mark it as if you had accepted it?
Guillaume
Guillaume on 14 Jan 2017
As is clearly explained in the help page, answers can only be accepted by somebody else after 7 days of inactivity by the original author.
Jan
Jan on 15 Jan 2017
@John BG: Marc can still decide, even if he knows why your solution in not efficient. Other readers and you can profit from this information also.

Sign in to comment.

Tags

Products