UNPKG

vega-regression

Version:

Regression transform for Vega dataflows.

62 lines (54 loc) 2.05 kB
import partition from './partition.js'; import {regressionLoess} from 'vega-statistics'; import {Transform, ingest} from 'vega-dataflow'; import {accessorName, inherits} from 'vega-util'; /** * Compute locally-weighted regression fits for one or more data groups. * @constructor * @param {object} params - The parameters for this operator. * @param {function(object): *} params.x - An accessor for the predictor data field. * @param {function(object): *} params.y - An accessor for the predicted data field. * @param {Array<function(object): *>} [params.groupby] - An array of accessors to groupby. * @param {number} [params.bandwidth=0.3] - The loess bandwidth. */ export default function Loess(params) { Transform.call(this, null, params); } Loess.Definition = { 'type': 'Loess', 'metadata': {'generates': true}, 'params': [ { 'name': 'x', 'type': 'field', 'required': true }, { 'name': 'y', 'type': 'field', 'required': true }, { 'name': 'groupby', 'type': 'field', 'array': true }, { 'name': 'bandwidth', 'type': 'number', 'default': 0.3 }, { 'name': 'as', 'type': 'string', 'array': true } ] }; inherits(Loess, Transform, { transform(_, pulse) { const out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS); if (!this.value || pulse.changed() || _.modified()) { const source = pulse.materialize(pulse.SOURCE).source, groups = partition(source, _.groupby), names = (_.groupby || []).map(accessorName), m = names.length, as = _.as || [accessorName(_.x), accessorName(_.y)], values = []; groups.forEach(g => { regressionLoess(g, _.x, _.y, _.bandwidth || 0.3).forEach(p => { const t = {}; for (let i=0; i<m; ++i) { t[names[i]] = g.dims[i]; } t[as[0]] = p[0]; t[as[1]] = p[1]; values.push(ingest(t)); }); }); if (this.value) out.rem = this.value; this.value = out.add = out.source = values; } return out; } });