Vega и Vega-Lite используют строгую типизацию полей, которая задаётся в канале encoding. Именно здесь формируется первичный уровень «неявной проверки»:
При несоответствии типов происходит автоматическое приведение,
которое часто выступает первой линией обнаружения ошибок. Например,
строка "42" может быть интерпретирована как число, а
некорректная дата — превращена в Invalid Date, что далее
может быть отфильтровано.
{
"mark": "line",
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {"field": "value", "type": "quantitative"}
}
}
Если поле date содержит некорректные строки, они будут
либо проигнорированы, либо приведены к невалидному значению в
зависимости от дальнейших трансформаций.
Основной механизм явной проверки данных в Vega-Lite — трансформация
filter. Она позволяет исключать строки на основе выражений,
написанных на языке выражений Vega.
Типичные задачи:
null и undefined{
"transform": [
{
"filter": "datum.value != null && isValid(datum.value)"
}
]
}
Функция isValid в Vega выражениях позволяет отделять
корректные значения от NaN, null и
undefined.
Более строгая проверка числового диапазона:
{
"transform": [
{
"filter": "datum.value >= 0 && datum.value <= 100"
}
]
}
Пропуски в данных являются одним из наиболее частых источников визуальных искажений. Vega-Lite не выполняет автоматическую иммутацию (в базовой конфигурации), поэтому стратегия обработки задаётся явно:
{
"transform": [
{
"filter": "datum.value != null"
}
]
}
Использование calculate позволяет формировать
производные поля с подстановкой значений по умолчанию:
{
"transform": [
{
"calculate": "datum.value != null ? datum.value : 0",
"as": "value_filled"
}
]
}
Такой подход создаёт новый слой данных без изменения исходного набора.
В Vega выражения поддерживают полноценную логическую алгебру, что позволяет строить многоуровневые проверки.
Пример проверки корректности записи:
{
"transform": [
{
"calculate": "isValid(datum.value) && datum.value > 0 ? datum.value : null",
"as": "validated_value"
}
]
}
Дальнейшая фильтрация:
{
"transform": [
{
"filter": "datum.validated_value != null"
}
]
}
Так формируется двухэтапная система проверки:
Временные ряды требуют отдельного уровня контроля, поскольку ошибки парсинга дат могут полностью исказить ось времени.
При указании типа temporal Vega-Lite пытается
автоматически распознать формат:
{
"encoding": {
"x": {"field": "timestamp", "type": "temporal"}
}
}
Однако при нестандартных форматах требуется явное преобразование:
{
"transform": [
{
"calculate": "toDate(datum.timestamp)",
"as": "parsed_time"
}
]
}
Дальнейшая проверка:
{
"transform": [
{
"filter": "isValid(datum.parsed_time)"
}
]
}
Особое значение имеет проверка диапазонов дат:
{
"transform": [
{
"filter": "datum.parsed_time >= datetime(2020, 0, 1)"
}
]
}
Проверка данных часто выходит за рамки синтаксической корректности и включает бизнес-ограничения.
Пример:
{
"transform": [
{
"filter": "datum.temperature >= -273.15"
}
]
}
Многоуровневая проверка:
{
"transform": [
{
"filter": "datum.value != null && datum.value >= 0 && datum.value <= 100"
}
]
}
Строковые поля часто содержат шум: лишние пробелы, разные регистры, нестандартизированные категории.
Используются выражения нормализации:
{
"transform": [
{
"calculate": "lower(trim(datum.category))",
"as": "category_norm"
}
]
}
После нормализации выполняется контроль допустимых значений:
{
"transform": [
{
"filter": "indexof(['a','b','c'], datum.category_norm) >= 0"
}
]
}
Vega-Lite не предоставляет встроенных статистических детекторов выбросов, но позволяет реализовать их вручную через агрегации и window-трансформации.
Сначала вычисляются статистики:
{
"transform": [
{
"aggregate": [
{"op": "mean", "field": "value", "as": "mean_value"},
{"op": "stdev", "field": "value", "as": "std_value"}
]
}
]
}
Далее применяется фильтрация:
{
"transform": [
{
"filter": "datum.value < datum.mean_value + 3 * datum.std_value"
}
]
}
В более сложных сценариях используется joinaggregate,
позволяющий сохранить исходные строки и статистику одновременно.
Одной из частых проблем является смешение типов в одном поле: числовые и строковые значения в одной колонке. Vega-Lite решает это через явное приведение:
{
"transform": [
{
"calculate": "toNumber(datum.value)",
"as": "value_num"
}
]
}
После приведения выполняется проверка:
{
"transform": [
{
"filter": "isValid(datum.value_num)"
}
]
}
На практике валидация данных строится как последовательность трансформаций:
Пример комбинированного pipeline:
{
"transform": [
{
"calculate": "toNumber(datum.value)",
"as": "value_num"
},
{
"filter": "isValid(datum.value_num)"
},
{
"filter": "datum.value_num >= 0"
},
{
"calculate": "lower(trim(datum.category))",
"as": "category_norm"
},
{
"filter": "datum.category_norm != ''"
}
]
}
Операция lookup позволяет проверять согласованность
данных через внешние справочники.
Пример проверки категорий:
{
"transform": [
{
"lookup": "category",
"from": {
"data": {
"values": [
{"key": "a"},
{"key": "b"}
]
},
"key": "key",
"fields": ["key"]
}
}
]
}
Если соответствие не найдено, поле становится null, что
далее может быть отфильтровано.
{
"transform": [
{
"filter": "datum.key != null"
}
]
}
После трансформации некорректные значения:
Линейные графики автоматически разрываются при наличии
null, что косвенно служит индикатором проблем в данных.
В Vega более низкоуровневый подход позволяет вводить сигналы для динамической проверки данных. Это даёт возможность строить интерактивную валидацию:
Сигналы комбинируются с фильтрами:
{
"signals": [
{"name": "minValue", "value": 0}
],
"data": [
{
"transform": [
{
"filter": "datum.value >= minValue"
}
]
}
]
}
Vega/Vega-Lite рассматривают некорректные данные не как исключения времени выполнения, а как часть потока значений. Это приводит к следующим особенностям:
nullТакой подход делает проверку данных не отдельным этапом, а встроенной частью трансформационного слоя визуализации.