UNPKG

study-overview

Version:

a high-level summary of study accrual and data cleaning metrics

153 lines (133 loc) 5.87 kB
import attachData from './summarizeData/attachData'; import calculateResults from './summarizeData/calculateResults'; export default function summarizeData(by = null) { const byValues = []; this.data.forEach(data => { // Match data spec to module. const module = this.settings.modules.find(module => module.spec === data.spec); // Attach data properties to module. if (module) { attachData.call(module, data); if (by) { module.byValues = d3 .set(data.data.map(d => d[by])) .values() .sort(); data.byValues = module.byValues.slice(); } else { delete module.byValues; delete data.byValues; } // nest by key variable const nest = (data, key, rollup = d => d.length) => { const overall = data.map(d => { const datum = Object.assign({}, d); datum[key] = '_overall_'; return datum; }); const nested = d3 .nest() .key(d => d[key]) .rollup(rollup) .entries(key ? data.concat(overall) : overall) .sort((a, b) => (a.key < b.key ? -1 : 1)); return nested; }; // transpose key values const transpose = (data, denominators) => { const transposed = data.reduce((acc, cur) => { const denominator = denominators ? denominators[cur.key].numerator : null; acc[cur.key] = { numerator: cur.values, denominator: denominator, value: denominator ? `${d3.format('6,d')(cur.values)} (${d3.format('2%')( cur.values / denominator )})` : d3.format('6,d')(cur.values) }; return acc; }, {}); return transposed; }; const summarize = (data, row = null, col = null, denominators = null) => { // summarize by col variable const colNest = nest(data, col); const colNestTransposed = transpose( colNest, denominators ? denominators.summary.row : null ); // summarize by row variable const rowNest = row ? nest(data, row, d => d) : null; const rowNestTransposed = row ? rowNest .map(row => { const nested = nest(row.values, col); nested.key = row.key; return nested; }) .map(row => { const transposed = transpose(row, colNestTransposed); transposed.key = row.key; return transposed; }) : null; return { row: colNestTransposed, rows: rowNestTransposed }; }; module.results.forEach(result => { result.data = module.data.slice(); result.subset.forEach(sub => { result.data = result.data.filter(d => sub.values.includes(d[sub.key])); }); result.summary = summarize( result.data, // data result.by, // row by, // col result.denominator // denominators ); }); data.summary = module.results .map(result => { const summary = []; if (result.summary.row) { const obj = { label: result.label, value: result.summary.row._overall_.value, level: 1 }; if (by) module.byValues.forEach(byValue => { obj[byValue] = result.summary.row[byValue] ? result.summary.row[byValue].value : null; }); summary.push(obj); } if (result.summary.rows) { result.summary.rows.forEach(row => { const obj = { label: row.key, value: row._overall_.value, level: 2 }; if (by) module.byValues.forEach(byValue => { obj[byValue] = row[byValue] ? row[byValue].value : null; }); summary.push(obj); }); } return summary; }) .reduce((acc, cur) => { cur.filter(d => d.label !== '_overall_').forEach(d => acc.push(d)); return acc; }, []); } else { console.warn(`Data specification [ ${data.spec} ] is invalid.`); } }); }