SummarizeColumn = (data, col) => {
let content, value, format, finiteFormat, el, chart, missing_label, pct_missing, min, max, median, mean, sd;
const notFiniteFormat = d3.format(",.0f");
const type = getType(data, col)
const col1 = htl.html`<td style="white-space: nowrap;vertical-align:middle;padding-right:5px;padding-left:3px;">${icon_fns[type]()}<strong style="vertical-align:middle;">${col === "" ? "unlabeled" : col}</strong></td>`
switch(type) {
case 'ordinal':
format = d3.format(",.0f")
const categories = d3.rollups(
data,
v => ({count:v.length, pct:v.length / data.length || 1}),
d => d[col]
).sort((a, b) => b[1].count - a[1].count)
.map(d => {
let obj = {}
obj[col] = (d[0] === null || d[0] === "") ? "(missing)" : d[0]
obj.count = d[1].count
obj.pct = d[1].pct
return obj
})
pct_missing = data.filter(d => (d[col] === null || d[col] === "")).length / data.length
const stack_chart = SmallStack(categories, col)
// element to return
el = htl.html`<tr style="font-family:sans-serif;font-size:13px;">
${col1}
<td><div style="position:relative;">${stack_chart}</div></td>
<td>${pct_format(pct_missing)}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>`;
value = {column: col, type, min:null, max: null, mean: null, median: null,
sd: null, missing:pct_missing, n_categories:categories.length}
break;
// Date columns
case "date":
// Calculate and format start / end
const start = d3.min(data, d => +d[col])
const end = d3.max(data, d => +d[col])
mean = d3.mean(data, d => +d[col]);
median = d3.median(data, d => +d[col]);
sd = d3.deviation(data, d => +d[col]);
// Calculate pct. missing
pct_missing = data.filter(d => d[col] === null || d[col] === "").length / data.length
chart = Histogram(data, col, type)
// Element to return
el = htl.html`<tr style="font-family:sans-serif;font-size:13px;">
${col1}
<td><div style="position:relative;">${chart}</div></td>
<td>${pct_format(pct_missing)}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>`
value = {column: col, type, min:start, max: end, mean: null, median: null,
sd: null, missing:pct_missing, n_categories:null}
break;
// Continuous columns
default:
// Compute values
min = d3.min(data, d => +d[col])
max = d3.max(data, d => +d[col])
mean = d3.mean(data, d => +d[col])
median = d3.median(data, d => +d[col])
sd = d3.deviation(data, d => +d[col])
if(Number.isFinite(sd)) {
finiteFormat = d3.format(",." + d3.precisionFixed(sd / 10) + "f");
format = x => Number.isFinite(x) ? finiteFormat(x) : notFiniteFormat(x);
}
else {
format = notFiniteFormat;
}
pct_missing = data.filter(d => d[col] === null || isNaN(d[col])).length / data.length
chart = Histogram(data, col, type)
// Element to return
el = htl.html`<tr style="font-family:sans-serif;font-size:13px;">
${col1}
<td><div style="position:relative;top:3px;">${chart}</div></td>
<td>${pct_format(pct_missing)}</td>
<td>${format(mean)}</td>
<td>${format(median)}</td>
<td>${format(sd)}</td>
</tr>`
value = {column: col, type, min, max, mean, median, sd, missing:pct_missing, n_categories:null}
break;
}
el.value = value;
el.appendChild(html`<style>td {vertical-align:middle;} </style>`)
return el
}