How to remove cell array satisfying specific conditions

Hi all,
I have a cell array with n vectors of different lengths m. I want to remove the cells, whose vectors satisfy a specific condition for which all the elements of the individual vectors need to be scanned. Something like that:
for c = 1 : length(cutForce)
for d = round(length(cutTime{c})/4) : round(3*length(cutTime{c})/4)% searching for data between the 1st and 3rd fourth of the vector
if min(cutForce{c}(d)) < 300
cutForce(c) = [];
end
end
end
Unfortunately the code doesn't work. I am new to programming. Help me please.

 Accepted Answer

There are two issues with your code:
- You're performing the min on just one element, since d is scalar. You either meant to just compare the element value to 300 (without min):
for d = ...
if cutForce{c}(d) < 300
...
or you meant to use min, in which case you did not need a loop:
d = round(...) : round(...) %d is just a list of indices
if min(cutForce{c})d) < 300
...
- More importantly, you are removing element of a sequence while you're iterating over an index of the sequence which does not know that elements have been remove. For example, imagine that when c = 2 your condition is true. You delete the second element, so third element becomes 2nd, 4th becomes third, etc. On the next pass of the loop, c becomes 3, which was the 4th element before. So you never test the original 3rd. Furthermore, when you reach the end, there's less elements than expected, so you're going to get an indexing error. The solution to this is to gather the list of indices to remove in the loop and perform the deletion afterward:
todelete = false(size(cutForce)); %vector that keeps track of which elements to delete
for c = 1:numel(cutForce) %I prefer numel to length as it works with n-d arrays.
testvector = cutForce{c}(round(numel(cutTime{c})/4) : round(3*numel(cutTime{c})/4));
%the above can also be written using the end keyword:
%testvector = cutForce{c}(round(end/4) : round(3*end/4));
todelete(c) = min(testvector) < 300; %either true or false
end
cutForce(todelete) = []; %delete all elements at once after the loop
You can also use cellfun instead of a loop:
todelete = cellfun(@(v) min(v(round(end/4):round(3*end/4))) < 300, cutForce);
cutForce(todelete) = [];

3 Comments

Hi Guillaume,
your suggestion seems logical, but unfortunately it does not remove any data. If you look at the chart attached, I wanted to remove the only line that is significantly different from the other curves (the one with the extra minimum at the middle) which the stated condition should do. I'll try to find a clue.
Btw. a few days ago I also posted a question concerning the same data, but nobody answered it. Maybe the question was to easy :) If you gave a glance at it, I would be very thankfull http://www.mathworks.com/matlabcentral/answers/244848-how-to-find-maximum-of-individual-cell-array-in-its-specific-range. Thank you a lot.
There was a stupid mistake in both of my codes that I've now fixed.
With the example matrices that you've posted 3 elements of cutForce are removed.
Great, now it works just the way I wanted. Thank you a lot. JH

Sign in to comment.

More Answers (1)

I have not looked at the details of your algorithm. One likely problem is that as you remove elements of the cell array inside your for loop, the index c begins to point to the wrong element. For example, if you happen to remove the first element, then the next time through the loop, c = 2 refers to the 2nd element of the shortened cell array, which is actually the 3rd element of the original vector.
There are a couple solutions. The easier one to understand for a beginner is to, in your for loop, only identify and store the elements you want to remove (say, in variable indicesToRemove), but don't remove them yet. Then, as a second step, do something like
cutForce(indicesToRemove) = [];
The more sophisticated way to do this is to use the cellfun command, which would allow you to test the condition on all cell array elements at once.

1 Comment

Thank you for your answer. It's similar to Guillamets.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

JH
on 25 Sep 2015

Commented:

JH
on 28 Sep 2015

Community Treasure Hunt

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

Start Hunting!