How to chop up/segment a periodic signal?
6 次查看(过去 30 天)
显示 更早的评论
I have a normal EKG signal (a periodic signal), and I 'd like to automatically chop up the signal into individual cycles (containing the P, QRS, and T waves). Could somebody please tell me how I can do that? I don't know the length of each cycle; should I calculate these precisely? Getting an approximate cycle length using autocorrelation would be good enough? The .mat file is attached.
Many thanks in advance!
采纳的回答
Star Strider
2022-9-7
This approach takes advantage of the fact that the Q-T interval in a normal EKG is less than one-half the previous R-R interval.
This will work for an EKG displaying regular sinus rhythm, however it might not work for atrial fibrillation (that would not then have an indentifable P-wave anyway).
LD = load(websave('ECG','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1119640/ECG.mat'))
ECG = LD.ECG;
Fs = 1024;
L = numel(ECG);
t = linspace(0, L-1, L)/Fs;
[pks,locs] = findpeaks(ECG, 'MinPeakProminence',0.5)
figure
plot(t, ECG)
hold on
plot(t(locs), pks, '^r')
hold off
grid
xlim([20 22.5])
for k = 1:numel(pks)-2
RR = (locs(k+1) - locs(k));
idxrng = locs(k+1) + (-fix(RR/2) : fix(RR/2));
ECGp{k} = ECG(idxrng);
end
figure
subplot(3,1,1)
plot(ECGp{20})
grid
title('Complex 20')
subplot(3,1,2)
plot(ECGp{100})
grid
title('Complex 100')
subplot(3,1,3)
plot(ECGp{200})
grid
title('Complex 200')
You could also use these to generate an ensemble average.
.
23 个评论
Susan
2022-9-7
@Star Strider Thank you very much! Truly appreciate it. Could you please kindly tell me how to use these to generate an ensemble average? If I'd like to know how much the ECGp{20} is different from the ECGp{600}, what is the best way to compare these two cycles?
Star Strider
2022-9-7
As always, my pleasure!
Sure!
LD = load(websave('ECG','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1119640/ECG.mat'))
LD = struct with fields:
ECG: [524798×1 double]
ECG = LD.ECG;
Fs = 1024;
L = numel(ECG);
t = linspace(0, L-1, L)/Fs;
[pks,locs] = findpeaks(ECG, 'MinPeakProminence',0.5);
figure
plot(t, ECG)
hold on
plot(t(locs), pks, '^r')
hold off
grid
xlim([20 22.5])
for k = 1:3%numel(pks)-2
RR = (locs(k+1) - locs(k));
idxrng = locs(k+1) + (-fix(RR/2) : fix(RR/2));
ECGp{k} = ECG(idxrng);
v = zeros(1,1000);
EKGe(k,500+(-fix(RR/2) : fix(RR/2))) = ECG(idxrng);
end
EKGensavg = mean(EKGe); % Trim Zeros & End Transients
EKGensavgv = EKGensavg~=0;
EKGensavg = EKGensavg(EKGensavgv);
EKGensavg = EKGensavg(2:end-1);
EKGensstd = std(EKGe); % Trim Zeros & End Transients
EKGensstdv = EKGensstd~=0;
EKGensstd = EKGensstd(EKGensstdv);
EKGensstd = EKGensstd(2:end-1);
figure
plot(EKGensavg, '-b', 'DisplayName','EKG Ensemble Average')
hold on
plot(EKGensavg+EKGensstd, '--r', 'DisplayName','+1 Standard Deviation')
plot(EKGensavg-EKGensstd, '--r', 'DisplayName','- 1 Standard Deviation')
hold off
legend('Location','best')
The slope derives from the initial transient in the original signal that is included in the segments. Choose a subset of the record that does not include that transient to get an ensemble average without it. That edited record then becomes the ‘ECG’ vector. The rest of the code should work without requiring any changes.
.
Susan
2022-9-7
@Star Strider Thanks a bunch again. Could you please kindly tell me if I'd like to compare two cycles, to see how much, for example, the ECGp{20} is different from the ECGp{500}, what the best way is to compare these two cycles? So far, I tried fft(), but it seems it doesn't provide me with much info.
Star Strider
2022-9-8
I am not certain how best to compare two different EKG cycles. From a statistical perspective, the Wilcoxon signed rank test (the signrank function) may be most appropriate, since they could be considered ‘paired’ data. Otherwise, doing a linear regression of one against the other would be an option.
Exploring those —
LD = load(websave('ECG','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1119640/ECG.mat'))
LD = struct with fields:
ECG: [524798×1 double]
ECG = LD.ECG;
Fs = 1024;
L = numel(ECG);
t = linspace(0, L-1, L)/Fs;
[pks,locs] = findpeaks(ECG, 'MinPeakProminence',0.5);
figure
plot(t, ECG)
hold on
plot(t(locs), pks, '^r')
hold off
grid
xlim([20 22.5])
for k = 1:numel(pks)-2
RR = (locs(k+1) - locs(k));
idxrng = locs(k+1) + (-fix(RR/2) : fix(RR/2));
ECGp{k} = ECG(idxrng);
end
EKG020 = ECGp{20};
EKG500 = ECGp{500};
[p,h,stats] = signrank(EKG020, EKG500)
p = 2.4750e-127
h = logical
1
stats = struct with fields:
zval: 24.0048
signedrank: 2.9595e+05
mdl = fitlm(EKG020, EKG500)
mdl =
Linear regression model:
y ~ 1 + x1
Estimated Coefficients:
Estimate SE tStat pValue
_________ __________ _______ ______
(Intercept) -0.018932 0.00019501 -97.083 0
x1 1.0032 0.0023175 432.89 0
Number of observations: 769, Error degrees of freedom: 767
Root Mean Squared Error: 0.00528
R-squared: 0.996, Adjusted R-Squared: 0.996
F-statistic vs. constant model: 1.87e+05, p-value = 0
figure
histfit(EKG020, 100)
title('Distribution Fit To ‘EKG020’')
figure
EKGdiff = EKG020-EKG500;
histfit(EKGdiff, 100)
title('Normal Distribution Fit To ‘EKG020’-‘EKG500’')
figure
EKGdiff = EKG020-EKG500;
histfit(EKGdiff(EKGdiff>0), 100, 'lognormal')
title('Lognormal Distribution Fit To ‘EKG020’-‘EKG500’')
% figure
% subplot(3,1,1)
% plot(ECGp{20})
% grid
% title('Complex 20')
% subplot(3,1,2)
% plot(ECGp{100})
% grid
% title('Complex 100')
% subplot(3,1,3)
% plot(ECGp{200})
% grid
% title('Complex 200')
So by both tests, they are not statistically significantly different.
It is important to consider how the data are distributed because statistical tests rest on certain assumptions about the data. The distrbution plots demonstrate that a single EKG segment is not normally distributed, however the difference between the two (using only positive values) comes closer to being lognormally-distributed than normally-distributed, at least by inspection. (Most physiological variables are lognormally distributed, at lelast in part because they can never be negative and in most instances are always greater than zero, the reason I chose this option.) There might be more appropriate distibutions, however the distribution needs to make sense in the context of the data, so for example fitting it to a Poisson distribution would not be appropriate, since these data are not arrival times.
I am not certain how else to compare them that would return a meaningful measure of their differences.
(My apologies for the delay — supper time and late-day news time intervened.)
.
Susan
2022-9-8
@Star Strider Thank you so much again for your detailed response. Whenever you answered my questions, I learned something new, mostly more than I expected. Truly appreciate it.
Two more questions here :)
1- you mentioned above, "The slope derives from the initial transient in the original signal ...... ". Do you think for the data set I have, I should choose a subset of the record that does not include that transient (ignore the transient part)? Or detrend the signal before any processing to get a signal without it? Or remove the baseline wander before any processing?
2- If we have two ECG cycles, does it make sense to consider one as a base and compare the second one with that? For example, the first cycle (the base one) is collected in a hospital, and the second one is in the street; I like to know how much the environment affects the ECG signal.
Star Strider
2022-9-8
Thank you!
‘Do you think for the data set I have, I should choose a subset of the record that does not include that transient (ignore the transient part)? Or detrend the signal before any processing to get a signal without it? Or remove the baseline wander before any processing?’
Either would work. The detrending approach would lilely involve fitting the curve to an exponential function and then subtracting it. An alternative might be to use the detrend function with a relatively high degree polynomial. (I was not able to get a good result with a filtering approach, so ploynomial detrending might be the most appropriate.)
‘If we have two ECG cycles, does it make sense to consider one as a base and compare the second one with that? For example, the first cycle (the base one) is collected in a hospital, and the second one is in the street; I like to know how much the environment affects the ECG signal.’
That’s an interesting problem! The hospital (with few interfering distractions of any sort) could be considered the ‘baseline’ and the ambulatory EKG outside the hospital might be considered data to be compared to it. The rate and rhythm (specifically rate variation) might be the only significant variations.
However to do any specific comparison of individual segments, I would use the ensemble average as the baseline for any single segment, and compare the others to it. (If there was any length discrepancy, the longer segment would temoprarily have to be reduced to the length of the shorter segment in order to do the comparison.)
.
Susan
2022-9-19
@Star Strider Hi there, I got some data regarding the last question I asked you. One data is considered the base signal (from an ideal environment like a hospital), and the other two sets are collected in different settings. By plotting the data, I can tell that these data have interfered compare to the base signal. However, it seems the rate of these signals is the same, and the mean peak-to-peak value doesn't change much. Any idea how I can measure the environment's effect on these EKG signals? Many thanks in advance!
Star Strider
2022-9-20
编辑:Star Strider
2022-9-20
This is an interesting problem!
I decided to compare them by doing a Lead II ensemble average on each situation (‘Env1’, ‘Env2’, ‘Hospital’) and then use a statistical test (friedman) to see if there were any differences between them. There are differences by this test, and appear to be highly significant —
LD1 = load(websave('Env2','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1129730/Env1.mat'))
LD1 = struct with fields:
Env1: [87297×8 table]
LD2 = load(websave('Env2','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1129735/Env2.mat'))
LD2 = struct with fields:
Env2: [92161×8 table]
LD3 = load(websave('Hospital','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1129740/Hospital.mat'))
LD3 = struct with fields:
Hospital: [30721×8 table]
Env1 = LD1.Env1;
Env2 = LD2.Env2;
Hosp = LD3.Hospital;
Fs = 1024; % Guess, Need Actual Value
L1 = size(Env1,1);
t1 = linspace(0, L1-1, L1)/Fs;
L2 = size(Env2,1);
t2 = linspace(0, L2-1, L2)/Fs;
L3 = size(Hosp,1);
t3 = linspace(0, L3-1, L3)/Fs;
ttlc = {'Env1','Env2','Hospital'};
EKGc = {Env1.II; Env2.II; Hosp.II}; % Create Array To Make Processing Easier
figure
subplot(3,1,1)
plot(t1, Env1.II)
grid
title('Env1')
xlim([0 10])
ylim([-0.2 0.6])
subplot(3,1,2)
plot(t2, Env2.II)
grid
title('Env2')
xlim([0 10])
ylim([-0.2 0.6])
subplot(3,1,3)
plot(t3, Hosp.II)
grid
title('Hospital')
xlim([0 10])
ylim([-0.2 0.6])
for k1 = 1:size(EKGc,1)
k1
ECG = EKGc{k1};
% Fs = 1024;
L = numel(ECG);
t = linspace(0, L-1, L)/Fs;
[pks,locs] = findpeaks(ECG, 'MinPeakProminence',0.5);
figure
plot(t, ECG)
hold on
plot(t(locs), pks, '^r')
hold off
grid
title(ttlc{k1})
xlim([20 22.5])
ylim([-0.2 0.6])
for k = 1:numel(pks)-2
RR = (locs(k+1) - locs(k));
idxrng = locs(k+1) + (-fix(RR/2) : fix(RR/2));
ECGp{k1}{k} = ECG(idxrng);
v = zeros(1,1000);
EKGe{k1}(k,500+(-fix(RR/2) : fix(RR/2))) = ECG(idxrng);
end
EKGensavg = mean(EKGe{k1}); % Trim Zeros & End Transients
EKGensavgv = EKGensavg~=0;
EKGensavg = EKGensavg(EKGensavgv);
EKGensavgc{k1,:} = EKGensavg(2:end-1);
end
k1 = 1
k1 = 2
k1 = 3
NrSp = size(EKGc,1);
figure
for k = 1:NrSp
subplot(NrSp,1,k)
plot(EKGensavgc{k})
grid
ylim([-0.2 0.6])
title(ttlc{k})
end
sgtitle('Ensemble AVerages')
MinSzc = min(cellfun(@(x)size(x,2),EKGensavgc)) % Minimum Length
MinSzc = 767
QF = factor(MinSzc)
QF = 1×2
13 59
EKGensavgct = cellfun(@(x)x(1:MinSzc),EKGensavgc,'Unif',0) % Trim All To Minimum Length
EKGensavgct = 3×1 cell array
{[-0.0251 -0.0285 -0.0255 -0.0307 -0.0359 -0.0333 -0.0266 -0.0261 -0.0325 -0.0360 -0.0311 -0.0252 -0.0274 -0.0341 -0.0354 -0.0293 -0.0253 -0.0297 -0.0357 -0.0343 -0.0274 -0.0256 -0.0313 -0.0359 -0.0323 -0.0258 -0.0266 -0.0334 -0.0361 -0.0304 -0.0251 -0.0281 -0.0346 -0.0350 -0.0285 -0.0253 -0.0303 -0.0358 -0.0334 -0.0266 -0.0259 -0.0322 -0.0360 -0.0313 -0.0251 -0.0269 -0.0337 -0.0354 -0.0293 -0.0250 -0.0290 -0.0353 -0.0346 -0.0278 -0.0254 -0.0307 -0.0355 -0.0322 -0.0256 -0.0260 -0.0326 -0.0357 -0.0305 -0.0250 -0.0278 -0.0345 -0.0352 -0.0286 -0.0249 -0.0295 -0.0352 -0.0332 -0.0264 -0.0255 -0.0318 -0.0358 -0.0314 -0.0251 -0.0267 -0.0335 -0.0356 -0.0296 -0.0247 -0.0282 -0.0344 -0.0338 -0.0271 -0.0244 -0.0298 -0.0349 -0.0321 -0.0254 -0.0254 -0.0320 -0.0353 -0.0303 -0.0247 -0.0271 -0.0337 -0.0347 -0.0284 -0.0245 -0.0290 -0.0350 -0.0335 -0.0265 -0.0249 -0.0308 -0.0354 -0.0315 -0.0252 -0.0261 -0.0327 -0.0349 -0.0292 -0.0242 -0.0277 -0.0344 -0.0344 -0.0276 -0.0247 -0.0299 -0.0353 -0.0327 -0.0259 -0.0253 -0.0316 -0.0353 -0.0305 -0.0243 -0.0263 -0.0331 -0.0345 -0.0281 -0.0238 -0.0280 -0.0344 -0.0334 -0.0265 -0.0246 -0.0303 -0.0348 -0.0311 -0.0244 -0.0251 -0.0318 -0.0346 -0.0293 -0.0240 -0.0270 -0.0335 -0.0339 -0.0272 -0.0240 -0.0290 -0.0348 -0.0327 -0.0257 -0.0247 -0.0309 -0.0349 -0.0305 -0.0245 -0.0263 -0.0331 -0.0347 -0.0285 -0.0239 -0.0278 -0.0342 -0.0335 -0.0265 -0.0239 -0.0293 -0.0343 -0.0312 -0.0245 -0.0248 -0.0314 -0.0343 -0.0291 -0.0236 -0.0263 -0.0329 -0.0334 -0.0264 -0.0214 -0.0244 -0.0284 -0.0245 -0.0156 -0.0122 -0.0164 -0.0187 -0.0124 -0.0035 -0.0023 -0.0066 -0.0065 0.0011 0.0076 0.0056 6.3125e-04 0.0025 0.0108 0.0151 0.0112 0.0077 0.0123 0.0209 0.0229 0.0181 0.0164 0.0230 0.0304 0.0295 0.0240 0.0240 0.0312 0.0360 0.0321 0.0266 0.0284 0.0355 0.0372 0.0313 0.0266 0.0302 0.0366 0.0356 0.0287 0.0260 0.0311 0.0358 0.0321 0.0249 0.0242 0.0303 0.0327 0.0267 0.0200 0.0210 0.0261 0.0250 0.0167 0.0109 0.0137 0.0181 0.0146 0.0065 0.0035 0.0081 0.0106 0.0043 -0.0039 -0.0049 -1.3393e-05 1.7589e-04 -0.0073 -0.0140 -0.0130 -0.0092 -0.0125 -0.0221 -0.0277 -0.0245 -0.0207 -0.0248 -0.0323 -0.0335 -0.0272 -0.0237 -0.0284 -0.0340 -0.0321 -0.0253 -0.0245 -0.0308 -0.0348 -0.0305 -0.0244 -0.0259 -0.0325 -0.0342 -0.0280 -0.0233 -0.0272 -0.0337 -0.0332 -0.0264 -0.0239 -0.0294 -0.0344 -0.0314 -0.0247 -0.0246 -0.0311 -0.0342 -0.0291 -0.0235 -0.0261 -0.0329 -0.0338 -0.0274 -0.0236 -0.0282 -0.0341 -0.0325 -0.0257 -0.0243 -0.0303 -0.0346 -0.0306 -0.0243 -0.0256 -0.0322 -0.0344 -0.0286 -0.0237 -0.0271 -0.0335 -0.0333 -0.0267 -0.0241 -0.0294 -0.0347 -0.0319 -0.0250 -0.0245 -0.0310 -0.0345 -0.0294 -0.0234 -0.0255 -0.0323 -0.0335 -0.0273 -0.0232 -0.0275 -0.0335 -0.0323 -0.0255 -0.0237 -0.0304 -0.0375 -0.0380 -0.0368 -0.0434 -0.0560 -0.0647 -0.0652 -0.0656 -0.0737 -0.0846 -0.0880 -0.0829 -0.0795 -0.0822 -0.0833 -0.0743 -0.0584 -0.0460 -0.0381 -0.0250 -9.2768e-04 0.0272 0.0497 0.0693 0.0961 0.1325 0.1687 0.1977 0.2254 0.2604 0.3011 0.3367 0.3633 0.3892 0.4213 0.4543 0.4774 0.4906 0.5031 0.5182 0.5263 0.5182 0.4993 0.4815 0.4677 0.4491 0.4206 0.3900 0.3663 0.3470 0.3215 0.2884 0.2573 0.2348 0.2144 0.1863 0.1528 0.1238 0.1028 0.0809 0.0507 0.0178 -0.0083 -0.0275 -0.0486 -0.0730 -0.0909 -0.0949 -0.0909 -0.0908 -0.0955 -0.0959 -0.0872 -0.0771 -0.0748 -0.0767 -0.0728 -0.0614 -0.0521 -0.0511 -0.0520 -0.0463 -0.0363 -0.0324 -0.0366 -0.0399 -0.0352 -0.0282 -0.0290 -0.0355 -0.0377 -0.0318 -0.0267 -0.0299 -0.0364 -0.0364 -0.0298 -0.0268 -0.0320 -0.0374 -0.0349 -0.0282 -0.0276 -0.0339 -0.0375 -0.0329 -0.0270 -0.0290 -0.0356 -0.0369 -0.0305 -0.0262 -0.0305 -0.0369 -0.0359 -0.0291 -0.0270 -0.0327 -0.0373 -0.0338 -0.0274 -0.0280 -0.0346 -0.0372 -0.0315 -0.0261 -0.0291 -0.0357 -0.0361 -0.0296 -0.0264 -0.0313 -0.0370 -0.0349 -0.0281 -0.0272 -0.0333 -0.0372 -0.0328 -0.0267 -0.0283 -0.0351 -0.0367 -0.0305 -0.0257 -0.0293 -0.0353 -0.0342 -0.0270 -0.0242 -0.0291 -0.0335 -0.0297 -0.0226 -0.0222 -0.0282 -0.0309 -0.0254 -0.0194 -0.0215 -0.0275 -0.0277 -0.0207 -0.0164 -0.0205 -0.0256 -0.0232 -0.0158 -0.0141 -0.0196 -0.0231 -0.0185 -0.0116 -0.0122 -0.0184 -0.0200 -0.0138 -0.0084 -0.0116 -0.0176 -0.0168 -0.0094 -0.0061 -0.0110 -0.0158 -0.0124 -0.0052 -0.0045 -0.0104 -0.0133 -0.0077 -0.0013 -0.0030 -0.0092 -0.0098 -0.0031 0.0015 -0.0022 -0.0076 -0.0056 0.0017 0.0038 -0.0017 -0.0058 -0.0015 0.0054 0.0050 -0.0011 -0.0030 0.0032 0.0089 0.0063 3.1161e-04 6.4643e-04 0.0078 0.0114 0.0069 0.0020 0.0048 0.0122 0.0134 0.0075 0.0042 0.0094 0.0160 0.0147 0.0085 0.0075 0.0142 0.0191 0.0154 0.0096 0.0109 0.0181 0.0206 0.0155 0.0114 0.0157 0.0232 0.0238 0.0181 0.0162 0.0225 0.0293 0.0277 0.0221 0.0227 0.0303 0.0349 0.0311 0.0264 0.0294 0.0371 0.0390 0.0338 0.0309 0.0362 0.0435 0.0432 0.0376 0.0369 0.0441 0.0499 0.0472 0.0419 0.0434 0.0513 0.0549 0.0505 0.0464 0.0505 0.0585 0.0596 0.0541 0.0519 0.0580 0.0646 0.0631 0.0574 0.0574 0.0648 0.0697 0.0662 0.0612 0.0634 0.0704 0.0718 0.0655 0.0609 0.0647 0.0709 0.0695 0.0622 0.0591 0.0637 0.0674 0.0626 0.0547 0.0534 0.0586 0.0601 0.0535 0.0467 0.0479 0.0533 0.0521 0.0441 0.0391 0.0424 0.0463 0.0418 0.0325 0.0283 0.0315 0.0325 0.0249 0.0154 0.0133 0.0169 0.0156 0.0068 -7.9286e-04 -1.5804e-04 0.0034 -3.2143e-04 -0.0098 -0.0148 -0.0114 -0.0080 -0.0129 -0.0210 -0.0225 -0.0171 -0.0151 -0.0215 -0.0282 -0.0270 -0.0213 -0.0220 -0.0297 -0.0348 -0.0312 -0.0256 -0.0277 -0.0347 -0.0365 -0.0304 -0.0259 -0.0301 -0.0365 -0.0357 -0.0290 -0.0267 -0.0322 -0.0371 -0.0338 -0.0271 -0.0274 -0.0340 -0.0370 -0.0318 -0.0262 -0.0289 -0.0356 -0.0363 -0.0298 -0.0262 -0.0308 -0.0364 -0.0344 -0.0276 -0.0266 -0.0329 -0.0371 -0.0329 -0.0266 -0.0278 -0.0343 -0.0362 -0.0304 -0.0257 -0.0295 -0.0361 -0.0358 -0.0291 -0.0262 -0.0314 -0.0365 -0.0336 -0.0270 -0.0270 -0.0335 -0.0368 -0.0316 -0.0258 -0.0282 -0.0351 -0.0362 -0.0299 -0.0259 -0.0303 -0.0362 -0.0346 -0.0277 -0.0262 -0.0323 -0.0367 -0.0329 -0.0264 -0.0274 -0.0341 -0.0366 -0.0309 -0.0258 -0.0290 -0.0355 -0.0354 -0.0286 -0.0256 -0.0309 -0.0364 -0.0338 -0.0270]}
{[ -0.0264 -0.0264 -0.0239 -0.0310 -0.0383 -0.0350 -0.0255 -0.0247 -0.0333 -0.0383 -0.0320 -0.0239 -0.0267 -0.0357 -0.0377 -0.0292 -0.0232 -0.0289 -0.0371 -0.0356 -0.0261 -0.0235 -0.0315 -0.0380 -0.0333 -0.0242 -0.0252 -0.0341 -0.0379 -0.0305 -0.0231 -0.0272 -0.0360 -0.0366 -0.0276 -0.0231 -0.0299 -0.0378 -0.0351 -0.0256 -0.0242 -0.0324 -0.0376 -0.0316 -0.0230 -0.0252 -0.0345 -0.0371 -0.0290 -0.0228 -0.0281 -0.0365 -0.0356 -0.0262 -0.0231 -0.0307 -0.0374 -0.0331 -0.0240 -0.0243 -0.0332 -0.0374 -0.0303 -0.0225 -0.0262 -0.0353 -0.0366 -0.0279 -0.0229 -0.0293 -0.0371 -0.0347 -0.0251 -0.0233 -0.0314 -0.0372 -0.0316 -0.0230 -0.0249 -0.0341 -0.0372 -0.0292 -0.0224 -0.0273 -0.0361 -0.0358 -0.0265 -0.0227 -0.0301 -0.0372 -0.0336 -0.0244 -0.0243 -0.0332 -0.0378 -0.0311 -0.0229 -0.0259 -0.0349 -0.0366 -0.0279 -0.0222 -0.0281 -0.0363 -0.0347 -0.0253 -0.0231 -0.0312 -0.0374 -0.0325 -0.0237 -0.0249 -0.0338 -0.0372 -0.0295 -0.0224 -0.0267 -0.0354 -0.0356 -0.0264 -0.0220 -0.0290 -0.0364 -0.0333 -0.0240 -0.0231 -0.0317 -0.0368 -0.0306 -0.0223 -0.0251 -0.0343 -0.0366 -0.0282 -0.0222 -0.0277 -0.0360 -0.0348 -0.0255 -0.0229 -0.0309 -0.0375 -0.0328 -0.0234 -0.0239 -0.0328 -0.0369 -0.0297 -0.0221 -0.0260 -0.0348 -0.0355 -0.0264 -0.0215 -0.0281 -0.0358 -0.0333 -0.0241 -0.0229 -0.0313 -0.0369 -0.0311 -0.0225 -0.0246 -0.0337 -0.0364 -0.0283 -0.0218 -0.0268 -0.0352 -0.0346 -0.0254 -0.0221 -0.0296 -0.0366 -0.0325 -0.0232 -0.0232 -0.0321 -0.0364 -0.0295 -0.0217 -0.0251 -0.0341 -0.0353 -0.0260 -0.0197 -0.0244 -0.0304 -0.0261 -0.0144 -0.0104 -0.0164 -0.0202 -0.0127 -0.0015 -7.0508e-04 -0.0074 -0.0085 0.0013 0.0099 0.0069 -2.6017e-04 0.0013 0.0120 0.0174 0.0118 0.0063 0.0116 0.0228 0.0250 0.0181 0.0150 0.0231 0.0326 0.0310 0.0230 0.0221 0.0314 0.0380 0.0329 0.0252 0.0271 0.0365 0.0389 0.0308 0.0243 0.0290 0.0379 0.0368 0.0275 0.0236 0.0308 0.0376 0.0327 0.0231 0.0220 0.0304 0.0340 0.0262 0.0175 0.0191 0.0269 0.0261 0.0158 0.0089 0.0134 0.0201 0.0160 0.0053 0.0015 0.0082 0.0125 0.0049 -0.0056 -0.0067 6.3051e-04 0.0017 -0.0077 -0.0164 -0.0142 -0.0076 -0.0108 -0.0226 -0.0294 -0.0245 -0.0186 -0.0237 -0.0335 -0.0350 -0.0263 -0.0214 -0.0280 -0.0359 -0.0335 -0.0240 -0.0225 -0.0308 -0.0365 -0.0310 -0.0225 -0.0245 -0.0337 -0.0366 -0.0286 -0.0220 -0.0269 -0.0354 -0.0349 -0.0258 -0.0224 -0.0298 -0.0368 -0.0329 -0.0236 -0.0235 -0.0323 -0.0369 -0.0302 -0.0222 -0.0254 -0.0343 -0.0358 -0.0271 -0.0217 -0.0278 -0.0358 -0.0338 -0.0242 -0.0220 -0.0302 -0.0364 -0.0313 -0.0225 -0.0239 -0.0329 -0.0363 -0.0286 -0.0217 -0.0261 -0.0347 -0.0348 -0.0258 -0.0218 -0.0289 -0.0362 -0.0329 -0.0234 -0.0228 -0.0315 -0.0366 -0.0303 -0.0222 -0.0250 -0.0341 -0.0361 -0.0275 -0.0217 -0.0274 -0.0356 -0.0341 -0.0247 -0.0223 -0.0311 -0.0401 -0.0395 -0.0358 -0.0424 -0.0573 -0.0671 -0.0656 -0.0639 -0.0732 -0.0865 -0.0901 -0.0825 -0.0776 -0.0820 -0.0850 -0.0752 -0.0564 -0.0432 -0.0372 -0.0257 -4.3136e-04 0.0299 0.0518 0.0690 0.0948 0.1332 0.1714 0.1991 0.2246 0.2599 0.3033 0.3397 0.3641 0.3878 0.4206 0.4560 0.4792 0.4901 0.5012 0.5177 0.5277 0.5185 0.4973 0.4791 0.4677 0.4504 0.4204 0.3878 0.3645 0.3476 0.3227 0.2876 0.2550 0.2337 0.2156 0.1871 0.1513 0.1215 0.1025 0.0825 0.0510 0.0157 -0.0106 -0.0272 -0.0468 -0.0726 -0.0921 -0.0954 -0.0890 -0.0889 -0.0959 -0.0976 -0.0871 -0.0748 -0.0735 -0.0778 -0.0745 -0.0607 -0.0499 -0.0508 -0.0539 -0.0478 -0.0350 -0.0304 -0.0369 -0.0420 -0.0361 -0.0266 -0.0273 -0.0361 -0.0395 -0.0319 -0.0248 -0.0291 -0.0378 -0.0381 -0.0290 -0.0249 -0.0320 -0.0394 -0.0361 -0.0266 -0.0257 -0.0344 -0.0395 -0.0334 -0.0250 -0.0274 -0.0364 -0.0386 -0.0303 -0.0243 -0.0299 -0.0383 -0.0372 -0.0278 -0.0251 -0.0329 -0.0394 -0.0349 -0.0257 -0.0262 -0.0352 -0.0391 -0.0319 -0.0244 -0.0283 -0.0371 -0.0380 -0.0291 -0.0244 -0.0309 -0.0386 -0.0360 -0.0265 -0.0251 -0.0336 -0.0393 -0.0336 -0.0251 -0.0271 -0.0362 -0.0388 -0.0306 -0.0239 -0.0287 -0.0368 -0.0357 -0.0260 -0.0220 -0.0290 -0.0355 -0.0310 -0.0212 -0.0207 -0.0289 -0.0328 -0.0254 -0.0171 -0.0202 -0.0286 -0.0293 -0.0200 -0.0142 -0.0198 -0.0270 -0.0243 -0.0145 -0.0122 -0.0199 -0.0253 -0.0194 -0.0101 -0.0111 -0.0196 -0.0223 -0.0141 -0.0069 -0.0112 -0.0193 -0.0186 -0.0088 -0.0043 -0.0109 -0.0175 -0.0135 -0.0037 -0.0029 -0.0111 -0.0155 -0.0083 5.0678e-04 -0.0018 -0.0105 -0.0119 -0.0029 0.0034 -0.0018 -0.0094 -0.0073 0.0027 0.0057 -0.0017 -0.0076 -0.0025 0.0068 0.0063 -0.0021 -0.0051 0.0028 0.0106 0.0071 -0.0011 -0.0010 0.0084 0.0134 0.0071 -1.7797e-05 0.0033 0.0133 0.0150 0.0070 0.0021 0.0085 0.0175 0.0157 0.0073 0.0055 0.0141 0.0205 0.0153 0.0074 0.0089 0.0189 0.0226 0.0155 0.0096 0.0150 0.0252 0.0259 0.0181 0.0150 0.0231 0.0318 0.0290 0.0211 0.0213 0.0313 0.0372 0.0317 0.0247 0.0280 0.0384 0.0411 0.0340 0.0295 0.0364 0.0461 0.0452 0.0372 0.0354 0.0443 0.0518 0.0477 0.0402 0.0418 0.0523 0.0568 0.0504 0.0443 0.0491 0.0594 0.0606 0.0530 0.0495 0.0573 0.0664 0.0643 0.0562 0.0557 0.0652 0.0717 0.0666 0.0596 0.0622 0.0721 0.0742 0.0658 0.0593 0.0641 0.0726 0.0707 0.0610 0.0569 0.0636 0.0694 0.0636 0.0535 0.0519 0.0595 0.0621 0.0536 0.0449 0.0468 0.0546 0.0537 0.0437 0.0373 0.0418 0.0479 0.0428 0.0312 0.0265 0.0319 0.0345 0.0254 0.0138 0.0118 0.0179 0.0175 0.0066 -0.0028 -0.0012 0.0047 8.2034e-04 -0.0110 -0.0172 -0.0119 -0.0063 -0.0120 -0.0223 -0.0241 -0.0163 -0.0130 -0.0210 -0.0297 -0.0280 -0.0199 -0.0202 -0.0302 -0.0369 -0.0319 -0.0239 -0.0265 -0.0357 -0.0382 -0.0301 -0.0239 -0.0293 -0.0379 -0.0371 -0.0278 -0.0245 -0.0321 -0.0389 -0.0347 -0.0256 -0.0259 -0.0348 -0.0391 -0.0321 -0.0243 -0.0278 -0.0368 -0.0380 -0.0292 -0.0240 -0.0303 -0.0382 -0.0360 -0.0267 -0.0250 -0.0334 -0.0393 -0.0338 -0.0250 -0.0265 -0.0355 -0.0383 -0.0302 -0.0234 -0.0283 -0.0371 -0.0370 -0.0280 -0.0244 -0.0317 -0.0387 -0.0349 -0.0257 -0.0255 -0.0344 -0.0392 -0.0327 -0.0246 -0.0275 -0.0364 -0.0379 -0.0293 -0.0238 -0.0298 -0.0379 -0.0361 -0.0266 -0.0242 -0.0321 -0.0383 -0.0333 -0.0243 -0.0255 -0.0346 -0.0382 -0.0305 -0.0233 -0.0278 -0.0366 -0.0369 -0.0278 -0.0236 -0.0305 -0.0379 -0.0348 -0.0255]}
{[ -0.0344 -0.0344 -0.0344 -0.0346 -0.0347 -0.0345 -0.0343 -0.0345 -0.0346 -0.0345 -0.0345 -0.0345 -0.0345 -0.0343 -0.0343 -0.0343 -0.0344 -0.0346 -0.0349 -0.0350 -0.0350 -0.0350 -0.0350 -0.0350 -0.0349 -0.0346 -0.0345 -0.0345 -0.0346 -0.0347 -0.0349 -0.0348 -0.0344 -0.0341 -0.0341 -0.0343 -0.0344 -0.0344 -0.0345 -0.0343 -0.0341 -0.0339 -0.0338 -0.0338 -0.0339 -0.0339 -0.0339 -0.0340 -0.0341 -0.0341 -0.0341 -0.0343 -0.0343 -0.0343 -0.0342 -0.0341 -0.0340 -0.0341 -0.0342 -0.0342 -0.0341 -0.0341 -0.0339 -0.0337 -0.0335 -0.0335 -0.0335 -0.0335 -0.0335 -0.0335 -0.0337 -0.0338 -0.0338 -0.0335 -0.0333 -0.0334 -0.0336 -0.0339 -0.0339 -0.0339 -0.0339 -0.0338 -0.0338 -0.0339 -0.0340 -0.0341 -0.0341 -0.0340 -0.0340 -0.0340 -0.0340 -0.0339 -0.0338 -0.0337 -0.0336 -0.0335 -0.0335 -0.0337 -0.0339 -0.0339 -0.0339 -0.0338 -0.0337 -0.0335 -0.0333 -0.0332 -0.0333 -0.0334 -0.0338 -0.0339 -0.0338 -0.0336 -0.0336 -0.0339 -0.0341 -0.0339 -0.0337 -0.0334 -0.0332 -0.0332 -0.0334 -0.0336 -0.0334 -0.0331 -0.0329 -0.0328 -0.0328 -0.0328 -0.0328 -0.0330 -0.0332 -0.0333 -0.0333 -0.0332 -0.0332 -0.0333 -0.0332 -0.0330 -0.0329 -0.0329 -0.0330 -0.0332 -0.0333 -0.0331 -0.0330 -0.0329 -0.0328 -0.0327 -0.0328 -0.0328 -0.0327 -0.0326 -0.0327 -0.0326 -0.0325 -0.0325 -0.0327 -0.0329 -0.0331 -0.0331 -0.0330 -0.0328 -0.0326 -0.0324 -0.0322 -0.0323 -0.0325 -0.0325 -0.0324 -0.0325 -0.0327 -0.0328 -0.0328 -0.0326 -0.0326 -0.0327 -0.0329 -0.0329 -0.0328 -0.0327 -0.0327 -0.0325 -0.0323 -0.0321 -0.0318 -0.0308 -0.0291 -0.0271 -0.0253 -0.0232 -0.0209 -0.0188 -0.0169 -0.0149 -0.0125 -0.0099 -0.0074 -0.0053 -0.0034 -0.0015 2.1316e-04 0.0017 0.0033 0.0049 0.0065 0.0079 0.0092 0.0108 0.0127 0.0146 0.0164 0.0184 0.0204 0.0221 0.0235 0.0246 0.0254 0.0263 0.0272 0.0278 0.0281 0.0283 0.0285 0.0289 0.0291 0.0290 0.0286 0.0283 0.0282 0.0281 0.0276 0.0271 0.0268 0.0264 0.0259 0.0252 0.0244 0.0234 0.0223 0.0212 0.0197 0.0181 0.0166 0.0151 0.0133 0.0115 0.0097 0.0080 0.0065 0.0052 0.0036 0.0018 -1.6316e-04 -0.0021 -0.0040 -0.0059 -0.0078 -0.0096 -0.0116 -0.0138 -0.0163 -0.0194 -0.0227 -0.0256 -0.0278 -0.0294 -0.0304 -0.0311 -0.0314 -0.0316 -0.0319 -0.0322 -0.0323 -0.0324 -0.0323 -0.0323 -0.0323 -0.0323 -0.0323 -0.0323 -0.0320 -0.0320 -0.0322 -0.0324 -0.0323 -0.0323 -0.0325 -0.0327 -0.0326 -0.0326 -0.0327 -0.0329 -0.0331 -0.0332 -0.0331 -0.0329 -0.0326 -0.0326 -0.0327 -0.0327 -0.0326 -0.0325 -0.0325 -0.0325 -0.0325 -0.0326 -0.0325 -0.0327 -0.0330 -0.0331 -0.0331 -0.0327 -0.0323 -0.0322 -0.0322 -0.0323 -0.0325 -0.0325 -0.0324 -0.0324 -0.0324 -0.0324 -0.0323 -0.0323 -0.0325 -0.0325 -0.0324 -0.0322 -0.0320 -0.0319 -0.0317 -0.0315 -0.0314 -0.0315 -0.0317 -0.0318 -0.0321 -0.0322 -0.0321 -0.0321 -0.0323 -0.0324 -0.0326 -0.0345 -0.0387 -0.0443 -0.0502 -0.0562 -0.0622 -0.0681 -0.0738 -0.0790 -0.0836 -0.0868 -0.0885 -0.0884 -0.0864 -0.0824 -0.0761 -0.0672 -0.0557 -0.0417 -0.0251 -0.0060 0.0153 0.0393 0.0655 0.0937 0.1235 0.1550 0.1879 0.2219 0.2564 0.2909 0.3249 0.3574 0.3880 0.4170 0.4440 0.4681 0.4887 0.5052 0.5165 0.5205 0.5160 0.5038 0.4864 0.4657 0.4430 0.4192 0.3945 0.3692 0.3432 0.3166 0.2898 0.2631 0.2363 0.2094 0.1824 0.1556 0.1289 0.1022 0.0754 0.0488 0.0223 -0.0041 -0.0307 -0.0560 -0.0762 -0.0892 -0.0963 -0.0991 -0.0990 -0.0969 -0.0938 -0.0903 -0.0862 -0.0816 -0.0768 -0.0719 -0.0667 -0.0614 -0.0560 -0.0508 -0.0461 -0.0426 -0.0401 -0.0384 -0.0374 -0.0367 -0.0361 -0.0358 -0.0357 -0.0358 -0.0359 -0.0359 -0.0358 -0.0358 -0.0357 -0.0356 -0.0355 -0.0355 -0.0357 -0.0358 -0.0358 -0.0358 -0.0358 -0.0357 -0.0353 -0.0351 -0.0353 -0.0354 -0.0355 -0.0355 -0.0353 -0.0351 -0.0353 -0.0352 -0.0350 -0.0349 -0.0350 -0.0351 -0.0354 -0.0357 -0.0358 -0.0357 -0.0357 -0.0355 -0.0354 -0.0353 -0.0353 -0.0353 -0.0351 -0.0348 -0.0347 -0.0349 -0.0350 -0.0351 -0.0350 -0.0347 -0.0344 -0.0343 -0.0344 -0.0346 -0.0347 -0.0348 -0.0350 -0.0349 -0.0345 -0.0341 -0.0336 -0.0330 -0.0325 -0.0320 -0.0315 -0.0309 -0.0302 -0.0295 -0.0289 -0.0284 -0.0279 -0.0272 -0.0266 -0.0262 -0.0257 -0.0251 -0.0245 -0.0241 -0.0237 -0.0233 -0.0227 -0.0220 -0.0213 -0.0208 -0.0204 -0.0199 -0.0192 -0.0185 -0.0181 -0.0177 -0.0174 -0.0171 -0.0165 -0.0159 -0.0153 -0.0146 -0.0139 -0.0134 -0.0130 -0.0125 -0.0120 -0.0115 -0.0110 -0.0105 -0.0100 -0.0094 -0.0088 -0.0083 -0.0079 -0.0074 -0.0069 -0.0064 -0.0058 -0.0051 -0.0047 -0.0044 -0.0039 -0.0033 -0.0027 -0.0023 -0.0020 -0.0014 -7.0526e-04 -4.2105e-05 5.8421e-04 0.0013 0.0018 0.0022 0.0025 0.0031 0.0036 0.0040 0.0047 0.0057 0.0065 0.0071 0.0075 0.0080 0.0084 0.0087 0.0090 0.0095 0.0101 0.0105 0.0107 0.0108 0.0112 0.0117 0.0123 0.0131 0.0142 0.0154 0.0166 0.0177 0.0189 0.0201 0.0211 0.0219 0.0227 0.0237 0.0248 0.0260 0.0271 0.0281 0.0293 0.0306 0.0318 0.0327 0.0336 0.0345 0.0355 0.0365 0.0374 0.0384 0.0396 0.0408 0.0420 0.0431 0.0442 0.0454 0.0466 0.0474 0.0483 0.0493 0.0504 0.0516 0.0527 0.0537 0.0545 0.0553 0.0562 0.0573 0.0583 0.0593 0.0605 0.0618 0.0629 0.0636 0.0639 0.0641 0.0641 0.0637 0.0632 0.0627 0.0622 0.0615 0.0606 0.0598 0.0589 0.0577 0.0564 0.0552 0.0539 0.0524 0.0509 0.0493 0.0479 0.0464 0.0450 0.0435 0.0420 0.0401 0.0378 0.0354 0.0327 0.0298 0.0268 0.0236 0.0204 0.0172 0.0140 0.0110 0.0082 0.0052 0.0021 -0.0011 -0.0041 -0.0072 -0.0104 -0.0128 -0.0148 -0.0165 -0.0182 -0.0197 -0.0211 -0.0223 -0.0237 -0.0251 -0.0264 -0.0274 -0.0284 -0.0298 -0.0313 -0.0325 -0.0336 -0.0342 -0.0345 -0.0346 -0.0346 -0.0345 -0.0345 -0.0346 -0.0346 -0.0348 -0.0349 -0.0349 -0.0350 -0.0354 -0.0355 -0.0353 -0.0352 -0.0351 -0.0352 -0.0352 -0.0352 -0.0351 -0.0348 -0.0348 -0.0347 -0.0345 -0.0343 -0.0343 -0.0344 -0.0344 -0.0344 -0.0345 -0.0344 -0.0342 -0.0341 -0.0343 -0.0344 -0.0343 -0.0343 -0.0341 -0.0340 -0.0341 -0.0343 -0.0345 -0.0345 -0.0344 -0.0342 -0.0342 -0.0343 -0.0343 -0.0342 -0.0341 -0.0341 -0.0340 -0.0339 -0.0338 -0.0341 -0.0344 -0.0346 -0.0347 -0.0347 -0.0345 -0.0342 -0.0340 -0.0340 -0.0341 -0.0341 -0.0339 -0.0336 -0.0336 -0.0338 -0.0339 -0.0339 -0.0338 -0.0336 -0.0335 -0.0337 -0.0341 -0.0342 -0.0342 -0.0340 -0.0340 -0.0339]}
EKGensavgt = cell2mat(EKGensavgct).'; % Column Matrix For Statistics
[p,EnsTable,Stats] = friedman(EKGensavgt, QF(2))
p = 4.2669e-16
EnsTable = 5×6 cell array
{'Source' } {'SS' } {'df' } {'MS' } {'Chi-sq' } {'Prob>Chi-sq'}
{'Columns' } {[1.8584e+05]} {[ 2]} {[9.2918e+04]} {[ 70.7810]} {[ 4.2669e-16]}
{'Interaction'} {[5.9515e+04]} {[ 24]} {[2.4798e+03]} {0×0 double} {0×0 double }
{'Error' } {[5.7618e+06]} {[2262]} {[2.5472e+03]} {0×0 double} {0×0 double }
{'Total' } {[6.0071e+06]} {[2300]} {0×0 double } {0×0 double} {0×0 double }
Stats = struct with fields:
source: 'friedman'
n: 13
meanranks: [96.2764 94.3859 76.3377]
sigma: 51.2396
I encourage you to do other tests on them to see if you can find any differences that might be physiologically significant, as well as statistically significant. Note that the ‘meanrank’ is lower for ‘Hospital’ than for the others. That could be due to any residual noise in the first two, however the ensemble averaging should significantly reduce it. Explaining that might be worth pursuing. Also consider filtering all of them (the sgolayfilt function might be easiest and most robust, however frequency-selective filters might also work) to elimiinate as much noise as possible without compromising the EKG morphology itself, and then see if the statistical significant differences remain.
This code sets up an approach (using ensemble averages) to use for these and other records that may allow you to detect differences.
EDIT — (20 Sep 2022 at 2:46)
Minor corrections to the comments, code unchanged.
.
Susan
2022-9-20
@Star Strider Thank you so much for your response and suggestions. Truly appreciate it.
I wasn't aware of Friedman's test, which was an exciting approach to solving this problem. I'll follow your suggestions and hope I can discover differences that are physiologically and statistically significant.
Susan
2022-9-21
@Star Strider I got two more questions for you and genuinely appreciate your feedback on them. I apologize in advance if I'm asking about the obvious
(1) Could you please kindly tell me why in the Friedman(EKGensavgt, QF(2))you consider QF(2)? It seems the results depend on the selection of the second argument of Friedman's function.
As part of my analysis, I want to know the signal variation in different environments. I've noticed that even though there is a significant difference between signals after filtering them, the peak-to-peak amplitude may not change noticeably. Still, the signal amplitude between two cycles/segments (marked in the below figure) does. Any idea how statistically I can calculate the range of this variation (peak to peak) for this part of the signal?
Star Strider
2022-9-21
Those are factors of the length of the records, since that is required by the friedman function. Use whichever of them you want.
Filtering should not change the peak amplitudes. It should only reduce the noise. The segments you emphasized are only a function of the rate. In the segmenting I did, the rate itself should not be a significant factor, since that information is effectively removed from the ensemble average. If it shows up at all, it will likely be a subtle change in the Q-T interval, since that is to an extent rate-dependent, although in the ensemble averages I posted earlier, I don’t see any differences between them.
The peak-to-peak interval variation is known as heart rate variability (HRV). There are a number of ways to characterise it, depending on the information you want from it. (I haven’t done anything with HRV is a very long time, so I’m not up on the current literature.) You likely need to do a PubMed search for that.
Susan
2022-9-22
@Star Strider Thank you so much again. Got it. Truly appreciate your help and the info.
Susan
2022-11-28
编辑:Susan
2022-11-28
@Star Strider Hi Star, I've got a question for you and truly appreciate your input. It's related to this post, but please let me know if I need to start a new thread.
I have some normal EKG signals that are effected by noise/interference, and I'd like to divide each signal by EKG cycle as you taught me here and find their peak to peak values—just wondering if I can still use the above method you mentioned for these noisy signals (I tried this method and it seems it's difficult to find QRS complex for some of these EKG signals). The EKG signals are attached here.
Many thanks in advance!
Star Strider
2022-11-29
The records do not appear to have any associated sampling frequencies or time vectors.
It would be helpful to know the sampling frequencies of each record.
Uz = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1211718/EKG%20signals.zip');
for k = 1:3
EKG{k,:} = struct2table(load(Uz{k+1}));
end
EKG
EKG = 3×1 cell array
{61441×1 table}
{61461×1 table}
{63837×1 table}
figure
for k = 1:3
subplot(3,1,k)
plot(EKG{k}{:,1})
grid
xlim([0 3500])
end
[Sp1,idx1] = findpeaks(EKG{1}{:,1}, 'MinPeakHeight',0.65)
Sp1 = 120×1
0.7223
0.7235
0.7650
0.7234
0.7195
0.7564
0.7131
0.7115
0.7606
0.7111
idx1 = 120×1
271
782
1294
1807
2319
2831
3342
3855
4366
4878
didx1 = diff(idx1)
didx1 = 119×1
511
512
513
512
512
511
513
511
512
512
[Sp2,idx2] = findpeaks(EKG{2}{:,1}, 'MinPeakHeight',max(EKG{2}{:,1})*0.90)
Sp2 = 282×1
0.5632
0.5703
0.5764
0.5640
0.5557
0.5487
0.5526
0.5682
0.5688
0.5571
idx2 = 282×1
467
473
479
976
990
1494
1503
2013
2015
2512
didx2 = diff(idx2)
didx2 = 281×1
6
6
497
14
504
9
510
2
497
14
The records have some serious anomalies. What are the random spikes? They do not appear to be pacemaker spikes. They do not appear to have any specific characteristics, either within a specific record or between different records, such that it would be possible to eliminate them. In ‘EKG1’ they appear to have the advantage of having a greater amplitude than the R-deflections, so they can be relatively easily detected. Eliminating them then requires finding their beginning and end points and setting everything between those points to NaN and then using the fillmissing function to interpolate the missing values.
That is not the situation for ‘EKG2’ and ‘EKG3’ so I am not certain if it is possible to reliably detect those, or eliminate them. I am not aware of a specific signal processing approach that would detect them.
The one feature that distinguishes the spikes from the QRS complexes is that the QRS complexes all appear to have distinct Q and S defiections, so detecting those would be important in distinguishing the QRS deflections from the spikes. The problem arises if a spike obscures a Q or S deflection. In that situation that approach would not work for that particular QRS complex.
That is the best I can do in advising you how to solve this. Of course, once the spikes are eliminated, my previous code will work to isolate the individual QRS compelxes.
.
Susan
2022-11-29
@Star Strider Thank you so much for your response, and I truly appreciate your suggestions. The associated sampling rate for all 8 EKG signals is 1024.
I am trying to figure out what the random spikes are. I collected a normal ECG signal in the presence of different noise signals, and the results are the attached EKG signals.
For what you suggested for EKG{1} signal, can I automatically figure out where the begining and end point of these spikes are?
Susan
2022-11-29
@Star Strider I found some info regarding the spikes and hope it will be helpful. For EKG{1} to EKG{4} of the attached signals, spikes happen every 0.5 sec, and the duration of spikes are 15ms, 30 ms,60ms, and 120ms for EKG{1} to EKG{4}, respectively.
Star Strider
2022-11-29
编辑:Star Strider
2022-11-29
As always, my pleasure!
Those are actual records and not artificially corrupted?
Something is seriously wrong with the instrumentation that would allow those spikes to be recorded as part of the EKG signal (actually added to it). Be sure you are using a neutral (right leg or some other point) reference that can be subtracted from the other leads to prevent this sort of corruption.
For ‘EKG1’ the spikes are (mostly) symmetrical about the identified peak, so it is relatively straightforward to identify them and the eliminate them by setting the identified index range to NaN and then using fillmissing. Here are examples of two separate such replacements —
Uz = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1211718/EKG%20signals.zip');
Fs = 1024;
for k = 1:3
EKG{k,:} = struct2table(load(Uz{k+1}));
L = numel(EKG{k});
t{k,:} = linspace(0, L-1, L).'/Fs;
end
t
t = 3×1 cell array
{61441×1 double}
{61461×1 double}
{63837×1 double}
EKG
EKG = 3×1 cell array
{61441×1 table}
{61461×1 table}
{63837×1 table}
figure
for k = 1:3
subplot(3,1,k)
plot(t{k}, EKG{k}{:,1})
grid
xlim([0 3.5])
% xlim([0 3500])
end
[Sp1,idx1] = findpeaks(EKG{1}{:,1}, 'MinPeakHeight',0.65);
t_spikes{1,:} = t{1}(idx1);
didx1 = diff(idx1);
% Lv = ischange(EKG{1}, 'Threshold',0.005);
figure
plot(t{1}, EKG{1}{:,1}, '.-')
hold on
plot(t_spikes{1}, Sp1, '^r')
idxrng{1} = idx1(1)+[-15:15]; % Identify First Spike
plot(t{1}(idxrng{1}), EKG{1}{idxrng{1},1}, '-g', 'LineWidth',2)
hold off
grid
title('Spike %3d',1)
xlim([0 0.65])
EKG{1}{idxrng{1},1} = NaN; % Assign Rnage To 'NaN'
EKG{1} = fillmissing(EKG{1}, 'makima'); % Interpolate 'NaN' Values To Eliminate First Spike
figure
plot(t{1}, EKG{1}{:,1}, '.-')
hold on
plot(t_spikes{1}, Sp1, '^r')
idxrng{1} = idx1(1)+[-15:15];
plot(t{1}(idxrng{1}), EKG{1}{idxrng{1},1}, '-g', 'LineWidth',2)
hold off
grid
title(sprintf('Spike %3d',1))
xlim([0 0.65])
figure
plot(t{1}, EKG{1}{:,1}, '.-')
hold on
plot(t_spikes{1}, Sp1, '^r')
% plot(t{1}(idxrng{10}), EKG{1}{idxrng{10},1}, '-g', 'LineWidth',2)
hold off
grid
title('Original Sample')
xlim([0 3.5])
for k = 1:numel(idx1) % Loop: Find & Eliminate All Identified Spikes
idxrng{k} = idx1(k)+[-15:15];
EKG{1}{idxrng{k},1} = NaN;
EKG{1} = fillmissing(EKG{1}, 'makima');
end
figure
plot(t{1}, EKG{1}{:,1}, '.-')
hold on
plot(t_spikes{1}, Sp1, '^r')
% plot(t{1}(idxrng{10}), EKG{1}{idxrng{10},1}, '-g', 'LineWidth',2)
hold off
grid
title('Sample With Spikes Removed')
xlim([0 3.5])
% xlim([0 0.65]+4.5)
% figure
% plot(t{1}, EKG{1}{:,1}, '.-')
% hold on
% plot(t_spikes{1}, Sp1, '^r')
% idxrng{10} = idx1(10)+[-15:15];
% % t{1}(idxrng{10})
% plot(t{1}(idxrng{10}), EKG{1}{idxrng{10},1}, '-g', 'LineWidth',2)
% hold off
% grid
% title(sprintf('Spike %3d',10))
% xlim([0 0.65]+4.5)
To figure out the index ranges for the spikes in ‘EKG1’ I simply counted the plotted points in the spike and then experimented to get these results. (I also experimented with the ischange function, however it does not give good results — detecting the beginning and ending of the spikes — here. You can experiment with findchangepts, however I doubt it wil do much better.) The only way to do this appears to manually characterise the spikes (as I did here). In ‘EKG1’ it is relatively easy to locate the spikes using findpeaks, and then using the manual indexing approach to eliminate them. That will likely not work for the other records. I have no idea what to suggest for those.
With respect to ‘EKG1’ this approach generally works (I did not examine the entire record in detail). It will be necessary for you to do something similar to the other records. Unfortunately, thare appears to be no specific way to identify the spikes in the other records, so it may be necessary for you to detect and define them (or define whatever characteristics are common to all of them) manually, however this general approach will work to eliminate them once you have solved that problem.
EDIT — Minor aesthetic changes.
.
Susan
2022-11-29
Thank you so very much again for your help! You gave me enough hints to work on other signals and figure out a way to eliminate unwanted spikes.
Yes, these records are actual records in a noisy scenario to measure an instrument's tolerance to the environment and are not artificially corrupted.
Star Strider
2022-11-29
As always, my pleasure!
I now get the impression that the intent here is to develop the instrumentation, and the EKG records are not the actual objective.
.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Applications 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)