簡単なクロス集計を実現するためのJavaScriptコードです。
縦軸・横軸・集計対象を指定すれば二次元配列で集計結果を確認できます。
随分探したのですが、ちょうどいいのがなかったので書き起こしました。
変換イメージ
元データ
shop | staff | month | price |
---|---|---|---|
新宿 | yamada | 5月 | 100 |
新宿 | yamada | 6月 | 200 |
渋谷 | tanaka | 5月 | 300 |
渋谷 | sato | 6月 | 400 |
クロス集計の結果
shop | staff | 5月 | 6月 |
---|---|---|---|
新宿 | 山田 | 100 | 200 |
渋谷 | 田中 | 300 | 0 |
渋谷 | 佐藤 | 0 | 400 |
使い方
元データの準備
- src_dataに2次元配列でデータを格納
- src_data_fieldsにフィールド名を指定
クロス集計の条件
- var pivot_row_fieldに横軸(表頭)を1つだけ指定
- var pivot_val_fieldに集計対象を1つだけ指定
- var pivot_col_fieldsに縦軸(表側)を指定 ※カンマ区切りで複数指定可
コード
pivot.js
// 対象データを二次元配列で定義
var src_data_fields = [ "shop", "staff", "month", "sales" ];
var src_data = [
[ "新宿", "山田", "5月", "100" ],
[ "新宿", "山田", "6月", "200" ],
[ "渋谷", "田中", "5月", "300" ],
[ "渋谷", "佐藤", "6月", "400" ]
];
// 設定条件
var pivot_row_field = "month"; // 横軸(表頭) ※1つだけ指定
var pivot_val_field = "sales"; // 集計対象 ※1つだけ指定
var pivot_col_fields = "shop,staff";// 縦軸(表側) ※カンマ区切りで複数指定可
// 処理用の変数
var agg_vals = {};
var pivot_row_vals_hash = {};
// 処理開始
var pivot_col_fields_array = pivot_col_fields.split(",");
for( var i = 0; i < src_data.length; i++ ){
// 処理しやすいようにレコードを連想配列化
var recs = {};
for( var j = 0; j < src_data_fields.length; j++ ){
recs[src_data_fields[j]] = src_data[i][j];
}
// 集計値の確認
var agg_val = parseInt( recs[pivot_val_field] );
if( ! agg_val ){
continue;
}
// 集計の縦軸
var key = "";
for( var j = 0; j < pivot_col_fields_array.length; j++ ){
key += "\t" + recs[ pivot_col_fields_array[j] ];
}
key = key.replace( /^\s+/, "" );
// 集計の横軸
var pivot = recs[pivot_row_field];
pivot_row_vals_hash[pivot] = 1;
// 縦軸・横軸の二次元で集計
if( typeof agg_vals[key] == "undefined" ){
agg_vals[key] = {};
}
if( typeof agg_vals[key][pivot] == "undefined" ){
agg_vals[key][pivot] = 0;
}
agg_vals[key][pivot] += agg_val;
}
// 横軸の値をソート ※ブラウザによってkeysが使えなのでforで回す
var pivot_row_vals = [];
for( var pivot_row_val in pivot_row_vals_hash ){
pivot_row_vals.push( pivot_row_val );
}
// 出力用配列の準備
var result = [];
var out_fields = [];
out_fields = out_fields.concat(pivot_col_fields_array);
out_fields = out_fields.concat(pivot_row_vals);
result.push( out_fields );
// 出力用データ
for( var agg_key in agg_vals ){
var out_row = [];
out_row = out_row.concat( agg_key.split("\t") )
for( var j = 0; j < pivot_row_vals.length; j++ ){
var cell_val = agg_vals[agg_key][pivot_row_vals[j]] || 0;
out_row.push(cell_val);
}
result.push(out_row);
}
console.log( JSON.stringify(result,null,2) );