В Vega-Lite агрегирование в кодировании задаёт способ преобразования
множества исходных значений в одно итоговое значение непосредственно на
уровне канала. Поле aggregate в описании encoding
определяет, как именно будут свёрнуты данные внутри группировки,
формируемой остальными каналами (чаще всего x,
y, color, detail,
row, column).
Семантически агрегирование в encoding выполняет ту же роль, что и
SQL-агрегаты в GROUP BY, но выражается декларативно внутри
спецификации визуализации.
Типичная форма записи:
{
data: { values: [...] },
mark: "bar",
encoding: {
x: { field: "category", type: "nominal" },
y: { aggregate: "sum", field: "value", type: "quantitative" }
}
}
В этом примере происходит группировка по category, а
затем вычисляется сумма value внутри каждой группы. Канал
y получает уже агрегированное значение.
Ключевое свойство:
aggregate применяется к каналу, а не к
данным в целомЛюбой канал в encoding можно рассматривать как фактор группировки, если он не агрегирован. Например:
x: category создаёт группы по категориямcolor: region дополнительно дробит группыdetail добавляет скрытое измерение группировки без
визуального каналаКогда задано:
encoding: {
x: { field: "category", type: "nominal" },
color: { field: "region", type: "nominal" },
y: { aggregate: "sum", field: "sales", type: "quantitative" }
}
фактически формируется группировка по паре
(category, region), после чего вычисляется сумма
sales.
Vega-Lite поддерживает набор стандартных агрегатов:
sum — сумма значенийmean — среднее арифметическоеmedian — медианаmin — минимумmax — максимумcount — количество записейdistinct — количество уникальных значенийvariance — дисперсияstdev — стандартное отклонениеargmin, argmax — значения, соответствующие
минимуму/максимуму другого поляПример использования среднего значения:
y: { aggregate: "mean", field: "temperature", type: "quantitative" }
Агрегат count отличается тем, что может не требовать
field.
y: { aggregate: "count", type: "quantitative" }
В этом случае считается количество записей в каждой группе, независимо от содержимого полей.
Если поле указано явно:
y: { aggregate: "count", field: "id" }
результат обычно эквивалентен подсчёту непустых значений этого поля,
что может отличаться при наличии null.
В Vega-Lite существует два подхода к агрегированию:
encoding.y.aggregate)transform: [{ aggregate: ... }])Пример encoding-агрегации:
encoding: {
x: { field: "type", type: "nominal" },
y: { aggregate: "sum", field: "amount" }
}
Эквивалент через transform:
transform: [
{
aggregate: [{ op: "sum", field: "amount", as: "total" }],
groupby: ["type"]
}
],
encoding: {
x: { field: "type" },
y: { field: "total" }
}
Ключевое различие:
Если в encoding указан aggregate, Vega-Lite
автоматически:
Если одновременно используются:
aggregatebintimeUnitпорядок обработки становится критичным.
Комбинация bin и aggregate часто
используется для гистограмм:
encoding: {
x: { bin: true, field: "value", type: "quantitative" },
y: { aggregate: "count" }
}
Здесь:
value разбиваются на интервалыФактически формируется распределение.
При работе с временными данными часто используется:
x: { timeUnit: "year", field: "date" }
y: { aggregate: "mean", field: "price" }
Это приводит к:
price в каждом годуNull-значения в Vega-Lite обычно:
sum, mean,
min, maxcount (если поле задано)Это поведение важно при работе с неполными данными, так как агрегаты не требуют предварительной очистки датасета.
Если несколько каналов содержат агрегаты, возникает сложная группировка:
encoding: {
x: { field: "category" },
color: { field: "region" },
y: { aggregate: "sum", field: "sales" },
size: { aggregate: "mean", field: "profit" }
}
Здесь:
sum(sales) считается по
(category, region)mean(profit) считается по тем же группамВажно, что все агрегированные каналы используют одинаковую группировку, заданную неагрегированными полями.
Агрегированные поля часто используются для сортировки:
encoding: {
x: {
field: "category",
type: "nominal",
sort: { op: "sum", field: "sales", order: "descending" }
},
y: { aggregate: "sum", field: "sales" }
}
Здесь сортировка выполняется на основе того же агрегата, который используется для визуализации, что обеспечивает согласованность представления.
Агрегирование становится основой для:
Пример тепловой карты:
{
mark: "rect",
encoding: {
x: { field: "day", type: "ordinal" },
y: { field: "hour", type: "ordinal" },
color: { aggregate: "mean", field: "load", type: "quantitative" }
}
}
Каждая ячейка представляет агрегированное значение по комбинации дня и часа.
Разные агрегаты дают разную интерпретацию данных:
sum отражает общий объёмmean сглаживает распределениеmedian устойчив к выбросамmin/max фиксируют экстремумыcount показывает плотность наблюденийВыбор агрегата напрямую влияет на смысл визуализации, даже если структура данных остаётся неизменной.
Агрегированные значения влияют на:
scale domain)Например, при aggregate: "sum" Vega-Lite пересчитывает
domain по суммарным значениям, а не по исходным записям.
На уровне компиляции Vega-Lite преобразует encoding-агрегацию в:
В Vega (низкоуровневом формате) это уже выражается через явные
aggregate трансформации.
Типичные проблемы при использовании aggregate:
field при неподдерживаемом агрегатеmean по номинальному
полю)bin и aggregate при неправильной
структуре encodingЕсли в encoding нет ни одного неагрегированного канала, Vega-Lite рассматривает весь набор данных как одну группу:
encoding: {
y: { aggregate: "sum", field: "value" }
}
В этом случае результат — одно значение, отображаемое одной геометрией.