mHelpMe
mHelpMe

Reputation: 6668

remove rows from cell based on multiple conditions

I have a cell with dimensions of 50 x 2. A subset of the table is shown below.

code   num
AAA    5
AAA    6
BBB    12
AAA    4
CCC    5

I want to find any rows where the code is equal to AAA and the num is not equal to 4. Then remove these rows to leave me with,

code   num
AAA    4
BBB    12
CCC    5

I have tried the following,

indx_remove = rf_cell(:, 1) == 'AAA' && rf_cell(:, 2) ~= '4';

This line gives me undefined function eq for input arguments of type cell.

Upvotes: 0

Views: 526

Answers (3)

kkuilla
kkuilla

Reputation: 2256

ind = cellfun(@(x,y) strcmp(x,'AAA') & y~=4, {A{:,1}}, {A{:,2}}) '
A(find(ind==0),:)
ans =
{
  [1,1] = BBB
  [2,1] = AAA
  [3,1] = CCC
  [1,2] =  12
  [2,2] =  4
  [3,2] =  5
}

Details

% // Create the values

A = {'AAA',    5;
'AAA'   , 6;
'BBB'   , 12;
'AAA'   , 4;
'CCC'   , 5};

%// Create a cell array of the values

{A{:,1}}, {A{:,2}}

ans =
{
  [1,1] = AAA
  [1,2] = AAA
  [1,3] = BBB
  [1,4] = AAA
  [1,5] = CCC
}
ans =
{
  [1,1] =  5
  [1,2] =  6
  [1,3] =  12
  [1,4] =  4
  [1,5] =  5
}

%// Create an anonymous function that will be applied to each element of our cell.
%// It will take the elements of the first cell (represented by `x` in the anonymous function)
%// and compare it to `AAA` and the elements of the second cell (`y`) and compare it to `4`.
%// The result is an array with the logical result of the conditions.

ind = cellfun(@(x,y) strcmp(x,'AAA') & y~=4, {A{1:size(A,1),1}}, {A{1:size(A,1),2}}) '

ind =

1
1
0
0
0

%// Then find the rows where these were zero as we wanted to exclude those values

A(find(ind==0),:)
ans =
{
  [1,1] = BBB
  [2,1] = AAA
  [3,1] = CCC
  [1,2] =  12
  [2,2] =  4
  [3,2] =  5
}

Upvotes: 1

Jens Boldsen
Jens Boldsen

Reputation: 1275

Use the following code:

A(strcmp(A(:,1),'AAA') &([A{:,2}]'~=4),:) = []

Upvotes: 2

GameOfThrows
GameOfThrows

Reputation: 4510

I believe I am doing this the hard way, but I hope it is not too stupid.

code num AAA 5 AAA 6 BBB 12 AAA 4 CCC 5

%generate code vector and num vector

code = ['AAA', 'AAA', 'BBB', 'AAA','CCC']

code = AAAAAABBBAAACCC

num = [5;6;12;4;5]

k = strfind(code, 'AAA') %find your index

k = 1 2 3 4 10 %because the vector code is just a concatenation of your sub-strings, you will need to sort the index out

%here, you can do something smart, your choice, I use modulo, since your char length is 3 characters, the modulo 3 should return 1 for it to be the starting index.

b = mod(k,3)

b = 1 2 0 1 1

index = k(find(b==1)) % 1, 4, 10 returned

column1 = floor(index/3+1) %output 1 2 4, which is the rows with AAA

check = num(floor(column1/3+1)) % just a checking stage, output 5 6 4 of num.

now you have the index of your column 1 for the strings that has AAA for value. Now you find for you column 2 the value 4s

column2 = find(num==4) % output 4

you can write a if statement to remove index [number 4] if both column1 and column2 contains the same number and remove that value (which refers to the index)

Happy coding!

Upvotes: 1

Related Questions