How to remove rows from cell array based on multiple conditions?

I would like to separate the following sample array into 2 arrays. If C contains any of the following strings (red, spoon, fork) within the row, I want to remove the row and put it into a new cell array.
clear all
clc
% Sample cell array
C = [{'A1';'A3';'A4';'A7'},{'blue';'green';'red';'blue'},{'spoon';'fork';'knife';'cup'},num2cell(rand(4,1))];
idx = cellfun(@(x) strcmp(x, 'red', 'spoon','fork'), C(:,:));
% Extracted data
C1 = C(idx,:);
% Others
C2 = C(~idx,:);
new arrays should look like...
C1 =
'A1' 'blue' 'spoon' [0.6948]
'A3' 'green' 'fork' [0.3171]
'A4' 'red' 'knife' [0.9502]
C2 =
'A7' 'blue' 'cup' [0.0344]

 Accepted Answer

E.g., assuming your columns are nice and are not mixed class:
C = your cell array
S = your cell string compare array, e.g., {'red', 'spoon','fork'}
x = cellfun(@ischar,C);
Cx = reshape(C(x),size(C,1),[]);
y = any(ismember(Cx,S),2);
C1 = C(y,:);
C2 = C(~y,:);

7 Comments

They are mixed classes and ideally I don't want to convert the numeric values to characters because I need to sum them later. Would that require any changes to the solution?
So, anything could be in any cell element? The char strings could be randomly mixed in with numeric data anywhere? There is no ordering by column as your example shows?
Columns 1, 2, and 3 are all character strings and column 4 is always numeric.
I didn't realize how much of a difference that would make or I would have specified in my original question. I modified my cell arrays in the question to reflect my needs more specifically.
The solution I posted should work as long as each column is either completely char or completely non-char. It doesn't matter where these columns are. E.g., either your original example or your current example is fine. What would not work is if there were char strings and numeric data in the same column. For that case, my posted code would need to be altered (e.g., by looping over the rows).
It works great for the example array, however when I apply it to the large array I am working with I get an error using reshape. Not all of my numeric values have the same character length. From what I read, I think that is causing the issue. Sometimes there is a NaN as well in the array, the NaN will always exist under columns 1, 2, and 3. i.e.
C =
'A1' 'blue' 'spoon' [0.6948]
'A3' NaN 'fork' [14.3171]
'A4' 'red' 'knife' [1.9502]
'A7' 'blue' 'cup' [11.0344]
If the numeric character length is the issue, it wouldn't be a problem reducing the numeric values to..
[0.6948]
[14.317]
[1.9502]
[11.034]
OK, since your columns can have mixed data type, I have converted my code to loop over the rows:
m = size(C,1);
y = true(m,1);
for k=1:m
x = cellfun(@ischar,C(k,:));
y(k) = any(ismember(C(k,x),S));
end
C1 = C(y,:);
C2 = C(~y,:);
This is extremely helpful, thank you!

Sign in to comment.

More Answers (0)

Categories

Asked:

on 15 Jul 2017

Commented:

on 15 Jul 2017

Community Treasure Hunt

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

Start Hunting!