UNPKG

melt-data

Version:

Javascript library inspired by the R reshape package

115 lines (102 loc) 2.93 kB
/*! * melt.js * http://git.io/melt * Copyright 2013 Jacob Rideout * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ melt = (function (undefined) { 'use strict'; function set(keys) { var s = {}, keys = keys || []; for (var i = 0; i < keys.length; i++) { s[keys[i]] = 1; } return s; } function extend(obj, copy) { for (var k in copy) { obj[k] = copy[k]; } return obj; } function melt(data, keep, varName, valName, noAddId) { var newData = [], varName = varName || 'variable', valName = valName || 'value', keepSet = set(keep); data.forEach(function (row, rowId) { var save = noAddId ? {} : {_id: rowId}, vars = [], vals = []; for (var k in row) { if (keepSet[k]) { save[k] = row[k]; } else { vars.push(k); vals.push(row[k]); } } for (var i = 0; i < vars.length; i++) { var newRow = {}; newRow[varName] = vars[i]; newRow[valName] = vals[i]; newData.push(extend(newRow, save)); } }); return newData; } function cast(data, keep, fun) { var funArgs = Array.prototype.slice.call(arguments, 3), keepData = {}, funStash = {}; data.forEach(function (row) { var newRow = {}; var aggKey = keep.map(function (key) { return newRow[key] = row[key]; }).join('\0'); if (!keepData[aggKey]) keepData[aggKey] = extend({}, newRow); var args = funArgs.slice(0); args.unshift(row, keepData[aggKey]); keepData[aggKey] = fun.apply(funStash, args); }); return Object.keys(keepData).map(function (k) { return keepData[k]; }); } cast.sum = function (row, acc, name, cols) { if (!this.sum) { var sum = function (row, acc, name, cols) { acc[name] = cols.reduce(function (a, k) { return a + row[k]; }, acc[name] || 0); return acc; }; this.sum = function (row, acc) { if (cols === undefined) cols = name; if (typeof (cols) == 'string') cols = [cols]; return sum(row, acc, name, cols); }; } return this.sum(row, acc); }; cast.count = function (row, acc, name) { if (!acc[name]) acc[name] = 0; acc[name] += 1; return acc; }; melt.cast = cast; return melt; })(undefined), cast = melt.cast;