如何在 Javascript 中将 RR (IBI) 数据转换为心率
How to convert RR (IBI) data to Heart Rate in Javascript
在做了一些研究之后,我决定在这里寻求建议,因为我不确定如何进行。
问题:
我有一组 RR (IBI) 数据
示例:[679, 686, 650...]
如何将其转换为心率?
我的研究:
- http://www.meddean.luc.edu/lumen/meded/medicine/skills/ekg/les1prnt.htm
- github 上的各种库,但 JS 上的 none 或者我可以移植到 JS 的某种方式
-
我的方法当然是有缺陷的:
for (const ibiInMilliseconds of eventJSONObject.DeviceLog["R-R"].Data) {
ibiBuffer.push(ibiInMilliseconds);
const ibiBufferTotal = ibiBuffer.reduce((a, b) => a + b, 0);
// If adding the ibi to the start of the activity is greater or equal to 2.5 second then empty the buffer there
if ((lastDate.getTime() + ibiBufferTotal) >= lastDate.getTime() + 2500) {
const average = ibiBuffer.reduce((total, ibi) => {
return total + ibi;
}) / ibiBuffer.length;
const avg = 1000 * 60 / average;
// I save this avg to a 1s list but it's very error prone
ibiBuffer = [];
lastDate = new Date(lastDate.getTime() + ibiBufferTotal);
}
}
如果能提供任何有关查找位置的帮助或指示,我将不胜感激。
我觉得其实更简单:
const hearbeats = [];
let beatCount = 0;
let time = 0;
for(const ibi of ibis){
time += ibi;
beatCount++;
if(time > 60 * 1000){
hearbeats.push(beatCount);
beatCount = time = 0;
}
}
(免责声明:我不知道我在说什么)
到目前为止,我从@jonas W 那里采用了修复时间和转换为 bpm(心率)的方法
/**
* Returns an Map of elapsed time and HR from RR data
* @param rr
* @param {number} sampleRateInSeconds
* @return {number[]}
*/
private static getHRFromRR(rr, sampleRateInSeconds?: number, smoothByAvg?: boolean): Map<number, number> {
sampleRateInSeconds = sampleRateInSeconds || 10; // Use any second number
const limit = sampleRateInSeconds * 1000;
let totalTime = 0;
let rrBuffer = [];
return rr.reduce((hr, d) => {
// add it to the buffer
rrBuffer.push(d);
// Increase total time
totalTime += d;
// Check if buffer is full
const time = rrBuffer.reduce((a, b) => a + b, 0); // gets the sum of the buffer [300+600 etc]
if (time >= limit) {
if (smoothByAvg) {
// @todo implement
} else {
hr.set(totalTime, rrBuffer.length * 60 / (time / 1000)); // convert to bpm
}
rrBuffer = [];
}
return hr;
}, new Map());
}
经过大量时间测试等,正确答案是:
/**
* Converts the RR array to HR instantaneus (what user sees)
* @param rrData
* @return {any}
*/
public static convertRRtoHR(rrData): Map<number, number> {
let totalTime = 0;
return rrData.reduce((hrDataMap: Map<number, number>, rr) => {
totalTime += rr;
hrDataMap.set(totalTime, Math.round(60000 / rr));
return hrDataMap;
}, new Map());
}
在做了一些研究之后,我决定在这里寻求建议,因为我不确定如何进行。
问题:
我有一组 RR (IBI) 数据
示例:[679, 686, 650...]
如何将其转换为心率?
我的研究:
- http://www.meddean.luc.edu/lumen/meded/medicine/skills/ekg/les1prnt.htm
- github 上的各种库,但 JS 上的 none 或者我可以移植到 JS 的某种方式 -
我的方法当然是有缺陷的:
for (const ibiInMilliseconds of eventJSONObject.DeviceLog["R-R"].Data) {
ibiBuffer.push(ibiInMilliseconds);
const ibiBufferTotal = ibiBuffer.reduce((a, b) => a + b, 0);
// If adding the ibi to the start of the activity is greater or equal to 2.5 second then empty the buffer there
if ((lastDate.getTime() + ibiBufferTotal) >= lastDate.getTime() + 2500) {
const average = ibiBuffer.reduce((total, ibi) => {
return total + ibi;
}) / ibiBuffer.length;
const avg = 1000 * 60 / average;
// I save this avg to a 1s list but it's very error prone
ibiBuffer = [];
lastDate = new Date(lastDate.getTime() + ibiBufferTotal);
}
}
如果能提供任何有关查找位置的帮助或指示,我将不胜感激。
我觉得其实更简单:
const hearbeats = [];
let beatCount = 0;
let time = 0;
for(const ibi of ibis){
time += ibi;
beatCount++;
if(time > 60 * 1000){
hearbeats.push(beatCount);
beatCount = time = 0;
}
}
(免责声明:我不知道我在说什么)
到目前为止,我从@jonas W 那里采用了修复时间和转换为 bpm(心率)的方法
/**
* Returns an Map of elapsed time and HR from RR data
* @param rr
* @param {number} sampleRateInSeconds
* @return {number[]}
*/
private static getHRFromRR(rr, sampleRateInSeconds?: number, smoothByAvg?: boolean): Map<number, number> {
sampleRateInSeconds = sampleRateInSeconds || 10; // Use any second number
const limit = sampleRateInSeconds * 1000;
let totalTime = 0;
let rrBuffer = [];
return rr.reduce((hr, d) => {
// add it to the buffer
rrBuffer.push(d);
// Increase total time
totalTime += d;
// Check if buffer is full
const time = rrBuffer.reduce((a, b) => a + b, 0); // gets the sum of the buffer [300+600 etc]
if (time >= limit) {
if (smoothByAvg) {
// @todo implement
} else {
hr.set(totalTime, rrBuffer.length * 60 / (time / 1000)); // convert to bpm
}
rrBuffer = [];
}
return hr;
}, new Map());
}
经过大量时间测试等,正确答案是:
/**
* Converts the RR array to HR instantaneus (what user sees)
* @param rrData
* @return {any}
*/
public static convertRRtoHR(rrData): Map<number, number> {
let totalTime = 0;
return rrData.reduce((hrDataMap: Map<number, number>, rr) => {
totalTime += rr;
hrDataMap.set(totalTime, Math.round(60000 / rr));
return hrDataMap;
}, new Map());
}