次のようなデータがあるとします。
harvest = [{type: "apple", color: "green", value: 1},
{type: "apple", color: "red", value: 2},
{type: "grape", color: "green", value: 3},
{type: "grape", color: "red", value: 4 }]
d3 の nest.rollup() 関数を使用して、さまざまな属性で合計できます。
sum_by = "color";
rollup = d3.nest().key(function(d) {
return d[sum_by];
}).rollup(function(d) {
return d3.sum(d, function(g) {
return g.value;
});
}).entries(harvest);
私にこれを与える:
rollup = [{key: "green", values: 4},
{key: "red", values: 6}]
これはまさに私が欲しいものです。
ただし、私のデータの値は配列で構成されており、すべて同じ長さです:
harvest = [{type: "apple", color: "green", values: [1,2,3,4]},
{type: "apple", color: "red", values: [5,6,7,8]},
{type: "grape", color: "green", values: [9,10,11,12]},
{type: "grape", color: "red", values: [13,14,15,16] }]
これらを同じように組み合わせることは可能ですか?たとえば、次のように指定します。
rollup = [{key: "green", values: [10,12,14,16]},
{key: "red", values: [18,20,22,24]}]
これはおそらくd3ロールアップ機能を使用して可能だと思います(ただし、必ずしもd3を使用する必要はありません)。
解像度
@meetamit と @Superboggly の努力のおかげで、私には 3 つの解決策があります。
reduce()
バージョン 1 (1回だけ使用するため推奨map()
):
function sumArrays(group) {
return group.reduce(function(prev, cur, index, arr) {
return {
values: prev.values.map(function(d, i) {
return d + cur.values[i];
})
};
});
}
バージョン 2:
function sumArrays(group) {
return group.map(function(h) {
return h.values;
}).reduce(function(prev, cur, index, arr) {
return prev.map(function(d, i) {
return d + cur[i];
});
});
}
バージョン 3 (配列の長さが異なる可能性があるため):
function sumArrays(group) {
return group.reduce(function(prev, cur, index, arr) {
return prev.map(function(d, i) {
return d + cur.values[i];
});
}, [0, 0, 0, 0]);
}
このように呼び出されます:
function rollupArrays() {
return d3.nest().key(function(d) {
return d[sum_by];
}).rollup(sumArrays).entries(harvest);
}
そして、CoffeeScript に変換します。
rollupArrays = ->
d3.nest().key (d) ->
d[sum_by]
.rollup(sumArrays).entries(harvest)
sumArrays = (group) ->
group.reduce (prev, cur, index, arr) ->
values: prev.values.map (d,i) ->
d + cur.values[i]
アップデート
このメソッドは、入力行が 1 つでも関数を実行する必要がある場合には適していません。パート IIを参照