-1

In Matlab, I have a cell of which the first column is composed of markers of which there are too many. We want to delete the entire row of the cell of these extraneous markers.

We have four marker types within the first column of our cell - '71', '72', '73' and '74': stored as strings. Whenever there is an occurrence of any of these markers, they are repeated ('71' '72' 23 times and '73' '74' 16 times). We want to keep the first presentation each time that markers occurs. Then for '71' '72' keep every 6th, whereas for '73' '74' keep every 4th.

The cell has length 550 so the blocks of 71, 72, 73 and 74 are repeated many times in the cell and there are other markers besides these four present as well that we want to keep.

A small part of the cell is shown below:

'12'    14737   29472
'31'    44747   89492
'4'     44771   89540
'53'    53756   107510
'73'    53831   107660
'73'    54082   108162
'73'    54331   108660
'73'    54582   109162
'73'    56081   112160
'73'    56331   112660
'73'    56581   113160
'73'    56831   113660
'73'    58330   116658
'73'    58580   117158
'73'    58829   117656
'73'    59079   118156
'73'    60579   121156
'73'    60829   121656
'73'    61079   122156
'73'    61329   122656
'63'    351340  702678
'4' 351361  702720
'54'    360342  720682
'74'    360375  720748
'74'    360633  721264
'74'    360883  721764
'74'    361133  722264
'74'    362632  725262
'74'    362882  725762
'74'    363132  726262
'74'    363382  726762
'74'    364881  729760
'74'    365131  730260
'74'    365381  730760
'74'    365631  731260
'74'    367130  734258
'74'    367380  734758
'74'    367630  735258
'74'    367880  735758
'64'    369374  738746
'4' 369379  738756
'51'    378376  756750
'71'    378409  756816
'71'    378584  757166
'71'    378750  757498
'71'    378917  757832
 **continued**

I'm not sure how to do this, I tried to use indices to approach this problem but have so far been unsuccessful.

Could anyone help?

Thanks

What I've tried so far:

function Y = correctRows(y)
Y.type = {};
Y.latency = [];
Y.latency_ms = [];


for i = 1:length(y)

if strcmp(y(i).type,'71') || strcmp(y(i).type,'72')
   Y(i) = y(i); 
    i = i+5;

elseif strcmp(y(i).type,'73') || strcmp(y(i).type,'74')
    Y(i) = y(i); 
    i = i+3;
else
    Y(ii) = y(i);
end 
end
Maheen Siddiqui
  • 539
  • 8
  • 19

2 Answers2

0

Here an example with a numerical array instead of a string array.

I think you get the transfer to strings yourself. The main idea of yours was not bad. But you did not define ii and I would rather use a while instead of a for loop.

This code only demonstrates how to cancel certain rows in a numerical Vector. The transfer to any other matrix / cell should be handled individually

clear all;
A=[12
31
4
53
73
73
73
73
73
73
73
73
73
73
73
73
73
73
73
73
63
4
54
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
64
4
51
71
71
71
71];

And now the code

counter=1;
Result=zeros(size(A));
i=1;
while k<=length(A)

if (A(k)==71 || A(k)==72)
    Result(counter,:) = A(i);
    k = k+6;
    counter=counter+1;
elseif (A(k)==73 || A(k)==74)
    Result(counter,:) = A(k);

    k = k+4;
    counter=counter+1;
else
    Result(counter,:) = A(k);
    k = k+1;
    counter=counter+1;
end

end
%delet unused rows
Results(counter:end)=[];
Irreducible
  • 864
  • 11
  • 24
0

I'd go for a scalable approach using a generic map (A is your cell):

%       markers      how-manieth   block size
map = { {'71' '72'}  6             23
        {'73' '74'}  4             16 };

for ii = 1:size(map,1)

    % Extract block
    blk  = cellfun(@(x) any(strcmp(x,map{ii,1})), A(:,1));

    % Find the how-manieth entry in each block
    inds = (mod(cumsum(blk), map{ii,3}) == map{ii,2});

    % Empty the rest
    A(xor(blk, inds),:)  = {[]};

end

% Remove all entries marked for removal
A = A(~cellfun('isempty',A(:,1)),:);

If there are also other keys that may be repeated, of which you'd need to keep only the first, then this may be more readable:

%       markers      how-manieth 
map = { {'71' '72'}, 6
        {'73' '74'}, 4 };

% The routine
output = cell(size(A));
index  = 1;

repetitions = 0;
repcount    = 0;
have_match  = false;

previous = '';

for ii = 1:size(A,1)

    % Current label
    current = A(ii,1);

    % If this label equals the previous one
    if strcmp(current, previous)

        repetitions = repetitions + 1;

        % First entry: 
        if repetitions==1

            % Check for mapped labels
            match = cellfun(@(x)any(strcmp(current,x)), map(:,1));
            if any(match)      
                % Mapped label found: 
                index      = index-1;
                repcount   = map{match,2};
                have_match = true;
            end

        % Subsequent entries
        elseif have_match && repetitions==repcount-1        
            output(index,:) = A(ii,:);
            index           = index + 1;
        end

    % Current label is not repeated; just insert the new data
    else
        have_match   = false;
        repcount     = 0;
        repetitions  = 0;

        output(index,:) = A(ii,:); 
        index           = index + 1;
    end

    previous = current;    
end

% Chop-off redundant entries
output(index:end,:) = [];
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96