How can I find adjacent identical values in a vector, flanked on either side by outliers?

9 Ansichten (letzte 30 Tage)
I am trying to find adjacent identical values in a vector, since they represent artifacts in heart rate data. So imagine 1Hz sample rate and we have a steadily climbing HR, then a stop, then it jumps to where it should be. I want to identify the suspect slope and the numbers before (and sometimes after) that value, so:
HR=[136 137 138 140 140 140 140 140 140 140 145 146 145 147]
according to certain literature, a slope over 2.6 bpm change/second is suspect, so I use diff...
a=diff(HR); %grabs the differences
b=a>2.6; %shows which ones are suspect
c=find(a==0); %shows where the slope is zero
and get
a =
1 1 2 0 0 0 0 0 0 5 1 -1 2
and
b =
0 0 0 0 0 0 0 0 0 1 0 0 0
and
c =
4 5 6 7 8 9
So the 10th element in the vector is my target, and the zero difference values (elements 4-9) in between are numbers that need to be replaced.
Is there some kind of way that I can use diff here? Is there a better solution?
Any thoughts would be welcome.
  4 Kommentare
Blake
Blake am 8 Mai 2015
We are not using waveform EKG, but rather instantaneous pulse rate. So something more like HR=[136 137 138 140 141 142 142 143 144 144 145 146 145 147]
where there is a gradual rise that does not violate the expected slope.
With respect to "numbers before (and sometimes after)", what I mean is that sometimes the series of identical adjacent values comes after a value greater than -2.6. So:
HR=[136 137 138 140 140 140 140 140 140 140 145 146 145 147 140 140 140 140 143 140 140 139];
In this case the questionable data is after the 147 point.
Blake
Blake am 8 Mai 2015
And also, it doesn't have to be diff... I am clutching at straws here and hoping for any decent solution.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Joseph Cheng
Joseph Cheng am 8 Mai 2015
Bearbeitet: Joseph Cheng am 11 Mai 2015
Keep in mind the comments from the cyclist and Star Strider but to use diff you can do something like this.
HR=[136 137 138 140 140 140 140 140 140 140 145 146 160 137 138 143 143 143 143 143 143 143 145 146 145 147]
a = [diff(HR)]; %find difference
c = a==0|abs(a)>2.6; %find points that fit your criteria.
dc = diff(c);
rangec = [find(dc==1)'+1 find(dc==-1)'];
spointind = find(diff(rangec ,[],2)==1)
rjump = rangec(spointind,:);
rangec(spointind ,:)=[]
%where rangec is the index ranges by of [start finish] index per detected segment.
now some additional conditionals manipulations could be needed to specifically determine if my 'OR' of the two conditions meets everything you want and filtering for single point changes meets all possible conditionals. but its a place to start and i know i included the target index in my range but that can be extracted.
  2 Kommentare
Joseph Cheng
Joseph Cheng am 8 Mai 2015
no... i accidentally missed it when i decided to quickly modify rc to rangec after i pasted it into the answer window. I thought it was a good idea but i didn't have the time before my meeting to rerun my edits.
but step through what i was trying to do and you should see that i did mean rangec. as the spointind is looking for ranges that have a difference of 1. which means there was a instantaneous jump of 1 point. This is because 0 10 0 diffed is [10 -10] which after performing the conditional statements and finding start and finish of ranges would have an index difference of 1. so in that like i find the points where you don't have leading/following consecutive same values.
Blake
Blake am 8 Mai 2015
This is great Joseph. I am going to play around with it for a bit and see what I can do with it. I accidentally deleted my comment to you before I saw that you had responded: I was trying to clarify what I was saying.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by