Intellijのデータエディター集計機能を使ってみる

2022.02.26

はじめに

データアナリティクス事業本部のkobayashiです。

IntellijをアップデートしたところDataGripにも新機能が追加されていました。その中で集計機能が便利だったのでその機能と独自のスクリプトを作成することでオリジナルの集計関数を作成できるのでその機能を試してみます。

環境

  • IntelliJ IDEA 2021.3.2

DataGripデータエディター集計機能

データエディターはDataGripで表示しているデータでセルを選択することで簡単な集計を行うことができます。SQLを書くまでもないような取り敢えず簡単にデータを確認したい場合に使えます。Excelのステータスバーが機能的に近いです。

また、デフォルトでは平均・合計・要素数などの9つの集計だけではなく、Groovyでスクリプトを書くことで独自の集計を行うこともできます。

機能を試してみる

早速データエディターの集計機能を試してみたいと思います。 集計機能はあくまでDataGripの機能でデータソースに依存することはないので適当なデータソースを使います。

集計値のステータスバー表示

Intellijでデータベースを開き適当なテーブルを開き、集計したい範囲を選択します。 この時点で下部のステータスバーに合計値・選択数・レコード数が表示されます。

集計値のビュー表示

集計範囲を選択した状態で右クリックをするとウィンドが開くのでShow Aggregate Viewを選択します。

これで集計ビューが開きます。集計ビューには以下の9種類が表示されます。

  • 平均
  • カラム数
  • 要素数
  • 数値型の要素数
  • 最大値
  • 中央値
  • 最小値
  • レコード数
  • 合計値

独自スクリプトを使った集計値の追加

SQLを書くことなく集計できてこれだけでも簡単に集計されたデータを確認することができるので大変便利なのですがこれ以外にも見たい統計指標があるかと思います。その場合はGroovyでスクリプトを書くことで実現可能です。

集計関数のGroovyのスクリプトはScratches and consoles / Extensions / Database Tools and SQL / data / aggregators配下に配置します。デフォルトの9つの集計関数もこちらのありますので独自スクリプトを書く場合は既存のスクリプトを参考に書けば特に問題なく動きます。

今回は標準偏差udf_STDと四分位数udf_QUARTILEを追加したいと思います。

Scratches and consoles / Extensions / Database Tools and SQL / data / aggregators配下にudf_STD.groovyudf_QUARTILE.groovyのファイルを作成し以下のスクリプトを記述します。

  • udf_STD.groovy
/*
 * Available context bindings:
 *   COLUMNS     List<DataColumn>
 *   ROWS        Iterable<DataRow>
 *   OUT         { append() }
 *   FORMATTER   { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
 *   TRANSPOSED  Boolean
 * plus ALL_COLUMNS, TABLE, DIALECT
 *
 * where:
 *   DataRow     { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
 *   DataColumn  { columnNumber(), name() }
 */

values = new ArrayList<BigDecimal>()
ROWS.each { row ->
  COLUMNS.each { column ->
    def value = row.value(column)
    if (value instanceof Number) {
      values.add(value as BigDecimal)
    }
    else if (value.toString().isBigDecimal()) {
      values.add(value.toString() as BigDecimal)
    }
  }
}
if (values.size() == 0) {
  OUT.append("Not enough values")
  return
}

avg = values.sum() / values.size()
var = values.inject(0){sum, v -> sum + Math.pow(v - avg,2) } / values.size()
sd = Math.sqrt(var)
OUT.append(sd.toString())
  • udf_QUARTILE.groovy
/*
 * Available context bindings:
 *   COLUMNS     List<DataColumn>
 *   ROWS        Iterable<DataRow>
 *   OUT         { append() }
 *   FORMATTER   { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
 *   TRANSPOSED  Boolean
 * plus ALL_COLUMNS, TABLE, DIALECT
 *
 * where:
 *   DataRow     { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
 *   DataColumn  { columnNumber(), name() }
 */

values = new ArrayList<BigDecimal>()
ROWS.each { row ->
    COLUMNS.each { column ->
        def value = row.value(column)
        if (value instanceof Number) {
            values.add(value as BigDecimal)
        } else if (value.toString().isBigDecimal()) {
            values.add(value.toString() as BigDecimal)
        }
    }
}
if (values.size() == 0) {
    OUT.append("Not enough values")
    return
}

elementsNumber = values.size()
Collections.sort(values)
if (elementsNumber % 2 != 0) { // odd
    q1 = values[new BigDecimal(elementsNumber).multiply(new BigDecimal("0.25")).intValue()];
    q2 = values[new BigDecimal(elementsNumber).multiply(new BigDecimal("0.5")).intValue()];
    q3 = values[new BigDecimal(elementsNumber).multiply(new BigDecimal("0.75")).intValue()];
} else { // even
    index = new BigDecimal(elementsNumber).divide(new BigDecimal("4")).intValue();
    q1 = values[index - 1].multiply(new BigDecimal("0.25")).add(values[index].multiply(new BigDecimal("0.75")));
    q2 = values[elementsNumber / 2].add(values[elementsNumber / 2 - 1]).divide(new BigDecimal("2"));
    index = new BigDecimal(3 * (elementsNumber + 1)).divide(new BigDecimal("4")).intValue();
    q3 = values[index - 1].multiply(new BigDecimal("0.75")).add(values[index].multiply(new BigDecimal("0.25")));
}
RES = [q1, q2, q3]
OUT.append(RES.toString())

これで再度集計ビューを表示すると標準偏差udf_STDと四分位数udf_QUARTILEが追加されていることが確認できます。

まとめ

Intellij(Datagrip)の2021.3で追加されたデータエディター集計を使ってみました。独自のスクリプトも書けるので「SQLを書かずに取り敢えずデータを集計してみたい」という場合にはとても有効だと思いました。 他にもテーブルビューや分割機能など使い勝手の良い機能が追加されていましたので是非アップデートをおすすめします。 やはりJetBrainsのツールは有料ですがそれだけの価値はあると思います。

最後まで読んで頂いてありがとうございました。