David Jiang
David Jiang

Reputation: 17

Deleting rows with specific rules

I got a 20*3 cell array and I need to delete the rows contains "137", "2" and "n:T"

Origin data:

'T'             ''          ''            
'NP(*)'         ''          ''            
[       137]    ''          ''            
[         2]    ''          ''            
'ARE'           'and'       'NP(FCC_A1#1)'
''              ''          '1:T'         
[      1200]    [0.7052]    ''            
[1.2051e+03]    [0.7076]    ''            
'ARE'           'and'       'NP(FCC_A1#3)'
''              ''          '2:T'         
[      1200]    [0.0673]    ''            
[1.2051e+03]    [0.0671]    ''            
'ARE'           'and'       'NP(M23C6)'   
''              ''          '3:T'         
[      1200]    [0.2275]    ''            
[1.2051e+03]    [0.2253]    ''            
[       137]    ''          ''            
[         2]    ''          ''    

And I want it to be like

'T'             ''          ''            
'NP(*)'         ''          ''                  
'ARE'           'and'       'NP(FCC_A1#1)'       
[      1200]    [0.7052]    ''            
[1.2051e+03]    [0.7076]    ''            
'ARE'           'and'       'NP(FCC_A1#3)'     
[      1200]    [0.0673]    ''            
[1.2051e+03]    [0.0671]    ''            
'ARE'           'and'       'NP(M23C6)'   
[      1200]    [0.2275]    ''            
[1.2051e+03]    [0.2253]    ''            

I've tried regexp and strcmp and they don't work well. Plus the cell array also hard to deal with. Can anyone help?

Thank you in advance.

Upvotes: 2

Views: 141

Answers (3)

Dan
Dan

Reputation: 45752

Here is another simple option:

%Anonymous function that checks if a cell is equal to 173 or to 2 or fits the '*:T*' pattern
Eq137or2 = @(x) sum(x == 137 | x == 2) | sum(strfind(num2str(x), ':T') > 1)

%Use the anonymous functions to find the rows you don't want
mask = = sum(cellfun(Eq137or2, a),2)

%Remove the unwanted rows
a(~mask, :)

Upvotes: 0

radarhead
radarhead

Reputation: 668

I just tried the following codes on my desktop and it seems to do the trick. I made a as the cell array you had.

L = size(a, 1);
mask = false(L, 1);
for ii = 1:L
    if isnumeric(a{ii, 1}) && (a{ii, 1} == 137 || a{ii, 1} == 2)
        mask(ii) = true;
    elseif ~isempty(a{ii, 3}) && strcmp(a{ii, 3}(end-1:end), ':T')
        mask(ii) = true;
    end
end

b = a(~mask, :)

Now, b should be the cell array you wanted. Basically, I created a logical mask that indicates the position of rows that satisfy the rules, then use the inverse of it to call out the rows.

Upvotes: 0

Luis Mendo
Luis Mendo

Reputation: 112669

If you can somehow read your original data so that all cells are strings or empty arrays (not numeric values), you can do it with strcmp and regexprep:

% The variable 'data' is a 2D-cell array of strings or empty arrays

datarep = regexprep(data,'^\d+:T','2'); % replace 'n:T' with '2' for convenience
remove1 = strcmp('2',datarep); % this takes care of '2' and 'n:T'
remove2 = strcmp('137',datarep); % this takes care of '137'
rows_keep = find(~sum(remove1|remove2,2)); % rows that will be kept
solution = data(rows_keep,:)

For example, with this data

'aa'     'bb'       'cc'  
'dd'     'dd'       '2'   
'137'    'dd'       'dd'  
'dd'     'dd'       '11:T'
'1:T'    '1:137'    'dd'  
'dd'     ''             []  

the result in the variable solution is

'aa'    'bb'    'cc'
'dd'    ''        []

Upvotes: 1

Related Questions