DTPab

DTPにまつわるあれこれ

条件を満たしたセルにある数値を吸い上げて中央値を取るカスタム関数(GAS)を書いた

まえがき

Google Sheetで中央値を取りたかったんですが、セル①にはJ3・21・39・57・75・93・111の中央値、セル②にはJ4・22・40・58・76・94・112の中央値、セル③には……という中央値が12個分欲しくて、かつ、ある場所の数値を変えると、異なるシートのJ列を参照する、みたいな処理を組み込みたかった(文字だけで伝わるのか?)。

それで書いたカスタム関数がこれ。

[GAS]特定のセルから数値を拾い上げ中央値(メディアン)を取る関数

とは言いつつ、自分のスプレッドシートに合わせてかなり限定的な書き方をしているので、参照する場合は適宜読み替えてください。

部分的に解説

変数名を見てもらうとわかるんですが、シート名が年度(2022、2021など)になっているスプレッドシートを対象としています。
なので変数tagetYearはそのままその名前のシートを参照しています。

変数targetMonthはそのとおり月なのですが、それがスプレッドシートでは3列目に書かれています。

const result = tagetValues.filter(el => el[2] == targetMonth).map(x => x[9]);

ここでel[2]となっているのはそのためです。3列目の値が指定したtargetMonthと同じであれば、Array.filter()メソッドで一旦拾います。
ドットチェーンでArray.map()メソッドを呼んでいるのは、実際には10列目に入っている値を中央値として算出するためで、Array.filter()メソッドで拾った二重配列からx[9]の値を取り出してresulet変数に配列として返しています。

JavaScriptのMathには中央値を演算するものがなかったので自分で実装したのがmedian()関数です。
中央値は、要素数が奇数であればその中から中央の値を、要素数が偶数であれば隣り合う中央の値の平均です。

謝辞

id:macneko-ayu 氏に相談したんですが、Array.map()メソッドが使えるかも…というアドバイスをいただいてドンピシャでした。てんきゅー!