datalib
Version:
JavaScript utilites for loading, summarizing and working with data.
103 lines (91 loc) • 2.77 kB
JavaScript
var util = require('./util'),
type = require('./import/type'),
stats = require('./stats'),
template = require('./template');
module.exports = {
table: formatTable, // format a data table
summary: formatSummary // format a data table summary
};
var FMT = {
'date': '|time:"%m/%d/%Y %H:%M:%S"',
'number': '|number:".4f"',
'integer': '|number:"d"'
};
var POS = {
'number': 'left',
'integer': 'left'
};
function formatTable(data, opt) {
opt = util.extend({separator:' ', minwidth: 8, maxwidth: 15}, opt);
var fields = opt.fields || util.keys(data[0]),
types = type.all(data);
if (opt.start || opt.limit) {
var a = opt.start || 0,
b = opt.limit ? a + opt.limit : data.length;
data = data.slice(a, b);
}
// determine char width of fields
var lens = fields.map(function(name) {
var format = FMT[types[name]] || '',
t = template('{{' + name + format + '}}'),
l = stats.max(data, function(x) { return t(x).length; });
l = Math.max(Math.min(name.length, opt.minwidth), l);
return opt.maxwidth > 0 ? Math.min(l, opt.maxwidth) : l;
});
// print header row
var head = fields.map(function(name, i) {
return util.truncate(util.pad(name, lens[i], 'center'), lens[i]);
}).join(opt.separator);
// build template function for each row
var tmpl = template(fields.map(function(name, i) {
return '{{' +
name +
(FMT[types[name]] || '') +
('|pad:' + lens[i] + ',' + (POS[types[name]] || 'right')) +
('|truncate:' + lens[i]) +
'}}';
}).join(opt.separator));
// print table
return head + "\n" + data.map(tmpl).join('\n');
}
function formatSummary(s) {
s = s ? s.__summary__ ? s : stats.summary(s) : this;
var str = [], i, n;
for (i=0, n=s.length; i<n; ++i) {
str.push('-- ' + s[i].field + ' --');
if (s[i].type === 'string' || s[i].distinct < 10) {
str.push(printCategoricalProfile(s[i]));
} else {
str.push(printQuantitativeProfile(s[i]));
}
str.push('');
}
return str.join('\n');
}
function printQuantitativeProfile(p) {
return [
'valid: ' + p.valid,
'missing: ' + p.missing,
'distinct: ' + p.distinct,
'min: ' + p.min,
'max: ' + p.max,
'median: ' + p.median,
'mean: ' + p.mean,
'stdev: ' + p.stdev,
'modeskew: ' + p.modeskew
].join('\n');
}
function printCategoricalProfile(p) {
var list = [
'valid: ' + p.valid,
'missing: ' + p.missing,
'distinct: ' + p.distinct,
'top values: '
];
var u = p.unique;
var top = util.keys(u)
.sort(function(a,b) { return u[b] - u[a]; })
.slice(0, 6)
.map(function(v) { return ' \'' + v + '\' (' + u[v] + ')'; });
return list.concat(top).join('\n');
}