R и Python в Power BI: скрипты, визуализации и обновление данных

R и Python в Power BI: скрипты, визуализации и обновление данных

Обновлено 3 сентября 2026 года.

R и Python в Power BI подходят для специальных преобразований, статистики и графиков, которых нет среди обычных визуализаций. Чтобы выбрать правильный способ работы, сначала определите результат: нужна таблица для модели или изображение на странице отчёта. От этого зависят место запуска кода, обновление и ограничения.

Скрипт не делает расчёты автоматически точными, а публикация PBIX не переносит в облако локальную среду со всеми библиотеками. Ниже — настройка, воспроизводимый пример с пропуском и повторяющимися продажами, различия Desktop и сервиса и порядок проверки перед публикацией.

Три способа использовать код

Способ Что получает код Что получает Power BI Когда меняется результат
Get data → Python script / R script Данные, которые читает или создаёт скрипт Таблицу DataFrame / data.frame При выполнении запроса загрузки
Run Python script / Run R script в Power Query Таблицу предыдущего шага как dataset Преобразованную таблицу для модели При обновлении запроса
Python visual / R visual Выбранные поля в текущем контексте отчёта Изображение графика При обновлении данных и поддерживаемых взаимодействиях отчёта

Если рассчитанная категория или прогноз должны участвовать в мерах DAX и других графиках, загрузите их как данные модели. Скрипт визуального элемента, который нарисовал картинку, не добавляет полученные значения в таблицы модели. Python в Power Query; R в Power Query.

Настройка локальной среды

  1. Установите нужный язык: Python из официального дистрибутива либо R. Для начала достаточно одного языка.
  2. Установите библиотеки в ту же среду, которую будет использовать Desktop. Для Python-примера ниже нужны pandas, NumPy и Matplotlib; для R-графика — ggplot2.
  3. В Desktop откройте File → Options and settings → Options. В глобальных настройках Python scripting или R scripting выберите установленную среду.
  4. Сначала выполните маленький скрипт загрузки и график, затем подключайте рабочие данные.

RStudio и Jupyter удобны для разработки, но не заменяют установленный runtime. Установка библиотеки в один Python и выбор другого в Power BI часто приводят к ModuleNotFoundError. Проверяйте путь и версии именно той среды, которая выполняет код. Настройка Python; Настройка R.

Импорт Python принимает pandas DataFrame, импорт R — data.frame. Скрипты загрузки, работающие дольше 30 минут, завершаются по тайм-ауту. Вызов, ожидающий ручного ввода, останавливает выполнение; для файлов используйте явные доступные пути. Это ограничения загрузки данных, а не лимиты визуального элемента.

Учебные данные: почему нужен ключ строки

Создайте таблицу Sales с шестью строками. RowID — уникальный номер строки продажи, Quantity и UnitPrice — числовые поля. Пустое Quantity в строке 4 означает неизвестное количество, а не ноль.

RowID Category Quantity UnitPrice Ожидаемая Revenue
1 A 2 100 200
2 A 2 100 200
3 B 1 50 50
4 B пропуск 80 не рассчитана
5 C 3 70 210
6 C 1 0 0

Первые две строки совпадают по категории, количеству и цене, но это две разные продажи. Их нельзя удалять как дубли по этим трём полям. Нулевая цена в строке 6 — отдельный бизнес-вопрос: в примере она допустима, и строка не отбрасывается.

Python в Power Query: расчёт с явной обработкой пропуска

Откройте Transform data, выберите таблицу и запустите Transform → Run Python script. Предыдущий шаг будет доступен как dataset. Код оставляет все строки и помечает те, для которых можно рассчитать сумму:

import numpy as np
import pandas as pd

required = {"RowID", "Category", "Quantity", "UnitPrice"}
missing = required.difference(dataset.columns)
if missing:
    raise ValueError("Missing columns: " + ", ".join(sorted(missing)))

clean = dataset.copy()
if clean["RowID"].isna().any() or clean["RowID"].duplicated().any():
    raise ValueError("RowID must be present and unique")

for column in ["Quantity", "UnitPrice"]:
    clean[column] = pd.to_numeric(clean[column], errors="coerce")

numbers = clean[["Quantity", "UnitPrice"]]
clean["IsValid"] = (
    numbers.notna().all(axis=1)
    & np.isfinite(numbers).all(axis=1)
    & clean["Category"].notna()
)
clean["Revenue"] = (
    clean["Quantity"] * clean["UnitPrice"]
).where(clean["IsValid"])

Выберите результирующий DataFrame clean и проверьте типы полей после возврата в Power Query. Получится шесть строк: пять с IsValid = true, одна — false. Revenue по известным значениям равна 660. Это известная сумма по пяти строкам, а не доказанная полная выручка по всем продажам: строку 4 ещё нужно исправить в источнике.

Читай также:  XML, JSON, базы данных и Lakehouse: как выбрать хранение данных

errors="coerce" переводит непарсящиеся значения в пропуски; код затем помечает их, а не скрывает заменой на ноль. Для денежных строк с запятыми, пробелами и символами валют сначала задайте явные правила разбора. Также отдельно определите правила возвратов, пустых категорий и диапазонов значений. Этот пример проверяет структуру и наличие конечных чисел, но не заменяет все бизнес-проверки. Документация pandas.to_numeric.

Python visual: график по подготовленным данным

Добавьте Python visual и поля RowID, Category, Revenue. Для числовых полей выберите «Не суммировать». RowID нужен даже тогда, когда его не будет на графике: без ключа Power BI может сгруппировать одинаковые строки до передачи в скрипт.

import matplotlib.pyplot as plt
import pandas as pd

data = dataset[["RowID", "Category", "Revenue"]].copy()
data["Revenue"] = pd.to_numeric(data["Revenue"], errors="coerce")
data = data.dropna(subset=["Category", "Revenue"])
totals = data.groupby("Category", sort=True)["Revenue"].sum()

fig, ax = plt.subplots(figsize=(7, 4))
if totals.empty:
    ax.text(0.5, 0.5, "No valid rows", ha="center", va="center")
    ax.set_axis_off()
else:
    ax.bar(totals.index.astype(str), totals.values, color="#2367a5")
    ax.set_xlabel("Category")
    ax.set_ylabel("Known revenue")
    ax.set_title("Revenue for rows with known values")
    ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
plt.show()

Без фильтров ожидаются A = 400, B = 50, C = 210. Выбор A в обычном срезе отчёта должен передать в скрипт соответствующий контекст и оставить столбец 400. Если не передать RowID, две строки A с Revenue = 200 могут превратиться в одну: тогда получится ошибочный итог 460 вместо 660.

Python visual показывает изображение. Оно реагирует на фильтры и подсветку от других элементов отчёта, но нажатие на нарисованный столбец не фильтрует остальные графики. Интерактивный HTML-виджет Plotly нельзя считать прямой заменой этого механизма. Устройство Python visual.

Тот же график на R

В R visual передайте те же RowID, Category, Revenue с сохранением детализации. Revenue должна иметь числовой тип в модели. Используем ggplot2 и уже рассчитанные суммы, а не количество записей:

library(ggplot2)

data <- dataset[!is.na(dataset$Category) & !is.na(dataset$Revenue), ]

if (nrow(data) == 0) {
  plot.new()
  text(0.5, 0.5, "No valid rows")
} else {
  totals <- aggregate(Revenue ~ Category, data = data, FUN = sum)
  p <- ggplot(totals, aes(x = Category, y = Revenue)) +
    geom_col(fill = "#2367a5") +
    labs(x = "Category", y = "Known revenue",
         title = "Revenue for rows with known values") +
    theme_minimal()
  print(p)
}

geom_col() использует переданные значения высот. Обычный geom_bar() без изменения статистики считает записи, что дало бы другой показатель. Результаты должны совпасть с Python: 400, 50 и 210. Различие geom_col и geom_bar.

R visual также получает сгруппированные поля и возвращает изображение. Его можно обновлять фильтрами отчёта, но нельзя использовать клики внутри картинки как обычный перекрёстный фильтр других визуализаций. Создание R visual в Desktop.

Лимиты Desktop и Power BI service

Сценарий Ограничение Практический вывод
Python visual в Desktop До 150 000 строк, до 250 МБ входных данных, до 5 минут вычисления Не передавайте в график весь массив событий без ограничения
R visual в Desktop До 150 000 строк, до 5 минут вычисления; изображение до 2 МБ Контролируйте детализацию и размер результата
Python visual в сервисе До 30 МБ суммарного сжатого входного пакета и скрипта, до 1 минуты Успех локального выполнения не гарантирует успех публикации
R visual в сервисе До 150 000 строк, до 250 МБ входа, до 60 секунд вычисления Проверяйте время на облачной среде

Ограничения приведены по текущей документации: Python Desktop, R Desktop, Python service, R service. Предупреждение об усечении строк означает неполный набор для расчёта, а не безобидное ограничение внешнего вида.

Пакеты и доступ к сети после публикации

Облачная среда визуализаций имеет собственные версии Python/R и список поддерживаемых пакетов. Локальная команда установки не добавляет библиотеку в сервис. Проверяйте не только имя пакета, но и версию и зависимости. Для Python-визуализаций сетевые клиент-серверные запросы в сервисе блокируются; нельзя рассчитывать, что код внутри графика скачает модель или запросит внешний API. Пакеты и ограничения Python; Поддержка пакетов R.

Читай также:  Российские BI-системы в 2026 году: сравнение и замена Power BI

Если нужен закрытый пакет, собственная модель или внешний API, выполните расчёт в управляемом процессе подготовки данных и загрузите результат в Power BI. Разделите получение данных и их показ: это упрощает повторный запуск, журналирование и проверку версии модели.

Как обновлять модель со скриптом Power Query

Для обновления опубликованной модели с R/Python-шагами Power Query используется on-premises data gateway в personal mode. На его компьютере должны быть совместимая среда и пакеты, а компьютер и шлюз должны оставаться доступными во время обновления. Это отличается от облачного выполнения скрипта визуализации при просмотре отчёта. Personal gateway и скрипты.

У этого подхода есть ограничение конфиденциальности: документация шагов R/Python в Power Query требует уровня Public для задействованных источников. Он управляет изоляцией данных при объединении запросов и не равен команде публикации отчёта в интернете. Однако назначать его конфиденциальным источникам только ради устранения ошибки неправильно. Если требования к изоляции несовместимы с таким режимом, перенесите преобразование за пределы Power Query. Ограничения Python-шагов; Смысл privacy levels.

Для командного процесса с требованиями к отказоустойчивости оцените выполнение R/Python в отдельном задании, например notebook или ETL-процессе, с записью результата в базу или lakehouse. Personal gateway привязан к одному пользователю и не предоставляет кластер высокой доступности. Рекомендации Microsoft по выбору шлюза.

Статистика и машинное обучение: что проверять

Не обучайте сложную модель заново при каждом изменении среза только потому, что visual позволяет выполнить код. Пользовательский фильтр может поменять обучающую выборку, а ограничение количества строк — незаметно обрезать её. Для рабочего прогноза обычно нужны отдельно подготовленная модель, версия обучения, дата расчёта и сохранённые прогнозы.

  • Отделяйте обучающие данные от проверки. Заполнение пропусков, масштабирование и отбор признаков должны обучаться на тренировочной части.
  • Для временного прогноза проверяйте результат на более поздних периодах и сравнивайте с простым базовым прогнозом.
  • Не считайте корреляцию доказательством причинного эффекта.
  • Не удаляйте выбросы автоматически: крупная продажа может быть настоящей, а возврат — законной операцией.
  • Разделяйте измеренное значение, оценку модели и пропуск; показывайте дату и область применимости расчёта.

Утечка данных при подготовке признаков способна сделать качество на проверке завышенным. Используйте воспроизводимый конвейер обработки и одинаковые преобразования при обучении и применении модели. Разбор ошибок подготовки данных в scikit-learn.

Проверка перед передачей отчёта

  1. Сравните количество входных строк и контрольную сумму с источником. Для примера: 6 строк, 1 пропуск, известная сумма 660.
  2. Проверьте отсутствие непреднамеренного объединения одинаковых продаж; сохраните ключ строки в полях visual.
  3. Проверьте пустой фильтр, одну категорию, некорректное число и отсутствующий столбец.
  4. Запустите обновление в сервисе и откройте отчёт под обычным пользователем; проверьте пакеты, время и права.
  5. Храните исходные скрипты, зависимости и контрольные данные вместе с версией отчёта. Не обещайте, что один PBIX автоматически решит слияние изменений нескольких разработчиков.
  6. Зафиксируйте владельца процесса, расписание и порядок реакции на ошибку. Старый успешный результат не должен выглядеть как новый расчёт.

При ошибке сначала выясните, какой слой её выдал: загрузка Power Query, Python/R runtime, облачный visual или шлюз. Затем воспроизведите её на небольшом наборе с теми же типами и версиями. Так исправление будет связано с конкретной причиной, а не со случайным обновлением всех библиотек.