НейроАгент

Исправление несоответствия stat_regline_equation в ggplot2

Устранение несоответствия между регрессионными уравнениями и линиями в ggplot2. Узнайте о ортогональных и сырых полиномах и реализуйте правильную квадратичную регрессию в R с примерами кода.

Почему уравнение регрессии из stat_regline_equation не совпадает с линией регрессии из stat_smooth в R?

Я столкнулся с проблемой, при которой создал диаграмму рассеяния с линией квадратичной регрессии с использованием ggplot2 в R. Линия регрессии отображается правильно с помощью stat_smooth(), но уравнение, выводимое stat_regline_equation(), не соответствует этой линии.

Вот код, который я использую:

r
#БИБЛИОТЕКИ
library(tidyverse)
library(ggpubr)
library(ggplot2)

test_db <- data.frame(
  X = c(0,-0.1297,-0.2185,-0.2795),
  Y = c(0.7569,0.7396,0.6561,0.5476)
)


test_plot = ggscatter(test_db, x = "X", y = "Y",
                     xlim = c(-1,0),
                     ylim = c(0, 1),
                     fill = "red",
                     shape = 23) +
  stat_regline_equation(label.x = -0.95, label.y = 0.15,  #вывести уравнение для линии регрессии
                        formula = y ~ poly(x, 2),         #установить линию регрессии как квадратичную
                        show.legend=FALSE) +
  stat_smooth(method = "lm",               #построить сглаженное условное среднее
              formula = y ~ poly(x, 2),    #установить линию регрессии как квадратичную
              colour="black", size=0.5,
              fill="red") + 
  theme_bw() + 
  labs(x = "X", 
       y = "Y",
       title = "Тестовый график")
test_plot

Что может вызывать это несоответствие между линией регрессии и отображаемым уравнением?

НейроАгент

Расхождение между stat_regline_equation и stat_smooth в вашем коде возникает из-за того, что функция poly() в R по умолчанию использует ортогональные полиномы, что может вызывать проблемы с интерпретацией коэффициентов, хотя теоретически подобранные регрессионные линии должны быть идентичны.


Содержание


Понимание проблемы с функцией Poly()

Корень вашей проблемы заключается в том, как функция poly() обрабатывает полиномиальные члены. Когда вы используете formula = y ~ poly(x, 2) в обеих функциях, R создает ортогональные полиномиальные члены по умолчанию, что может привести к неожиданным результатам при интерпретации коэффициентов.

Согласно документации ggpubr, stat_regline_equation внутренне использует функцию lm(), но способ обработки poly() может различаться между stat_smooth и stat_regline_equation в отношении параметров по умолчанию.

Вопрос на Stack Overflow (R stat_regline_equation doesn’t match stat_smooth line) демонстрирует именно эту проблему и показывает, что добавление raw=TRUE решает вопрос.


Ортогональные vs сырые полиномы

Давайте проясним ключевое различие:

Ортогональные полиномы (по умолчанию)

r
poly(x, 2)  # По умолчанию использует ортогональные полиномы
  • Создает некоррелированные полиномиальные члены
  • Лучше для численной стабильности
  • Коэффициенты представляют вклады из ортогонализированных членов
  • Труднее интерпретировать напрямую

Сырые полиномы

r
poly(x, 2, raw = TRUE)  # Использует сырые полиномиальные члены
  • Создает стандартные члены x и x²
  • Коэффициенты представляют ожидаемую математическую зависимость
  • Легче интерпретировать и соответствует ручным расчетам

Важное замечание: Оба подхода должны давать одинаковую подобранную регрессионную линию, но значения коэффициентов будут значительно отличаться. Проблема в вашем случае, вероятно, связана с тем, как разные слои ggplot2 обрабатывают функцию poly().


Различия между stat_smooth и stat_regline_equation

Хотя обе функции внутренне используют линейные модели, они имеют разные поведения по умолчанию:

Функция Обработка формулы по умолчанию Подгонка модели Фокус вывода
stat_smooth() Прямая обработка формулы в контексте ggplot2 Подгоняет модель для визуализации Создает сглаженную линию с доверительными интервалами
stat_regline_equation() Обработка формулы через обертку lm ggpubr Подгоняет модель для отображения уравнения Извлекает коэффициенты и R² для текстового вывода

Исходный код на GitHub для stat_regline_equation показывает, что он использует lm(), но может иметь разную обработку параметров по сравнению с stat_smooth ggplot2.


Решения для устранения расхождения

Решение 1: Использовать raw=TRUE (Рекомендуется)

Измените ваш код, чтобы явно использовать сырые полиномы:

r
test_plot = ggscatter(test_db, x = "X", y = "Y",
                     xlim = c(-1,0),
                     ylim = c(0, 1),
                     fill = "red",
                     shape = 23) +
  stat_regline_equation(label.x = -0.95, label.y = 0.15,
                        formula = y ~ poly(x, 2, raw = TRUE),  # Использовать raw=TRUE
                        show.legend=FALSE) +
  stat_smooth(method = "lm",
              formula = y ~ poly(x, 2, raw = TRUE),  # Использовать raw=TRUE
              colour="black", size=0.5,
              fill="red") + 
  theme_bw() + 
  labs(x = "X", y = "Y", title = "Тестовый график")

Решение 2: Использовать сырые полиномиальные члены напрямую

Альтернативный подход - вручную создать полиномиальные члены:

r
test_db <- test_db %>%
  mutate(x2 = X^2)  # Создать член x² вручную

test_plot = ggscatter(test_db, x = "X", y = "Y",
                     xlim = c(-1,0),
                     ylim = c(0, 1),
                     fill = "red",
                     shape = 23) +
  stat_regline_equation(label.x = -0.95, label.y = 0.15,
                        formula = y ~ X + x2,  # Использовать сырые члены напрямую
                        show.legend=FALSE) +
  stat_smooth(method = "lm",
              formula = y ~ X + x2,  # Использовать сырые члены напрямую
              colour="black", size=0.5,
              fill="red") + 
  theme_bw() + 
  labs(x = "X", y = "Y", title = "Тестовый график")

Решение 3: Проверить согласованность модели

Вы также можете подогнать модели отдельно, чтобы убедиться, что они идентичны:

r
# Подогнать модель вручную
manual_model <- lm(Y ~ poly(X, 2, raw = TRUE), data = test_db)
summary(manual_model)

# Сравнить с тем, что produces stat_smooth
ggplot(test_db, aes(x = X, y = Y)) +
  geom_point() +
  stat_smooth(method = "lm", formula = y ~ poly(x, 2, raw = TRUE))

Лучшие практики для полиномиальной регрессии в ggplot2

  1. Всегда указывайте raw = TRUE при использовании poly() в регрессионных уравнениях для обеспечения последовательной интерпретации

  2. Будьте осторожны с небольшими наборами данных - В вашем примере всего 4 точки данных, квадратичная регрессия может быть переобучена

  3. Учитывайте количество параметров - Квадратичная модель с 4 точками данных использует 3 параметра (пересечение, линейный, квадратичный), оставляя только 1 степень свободы

  4. Проверяйте вашу модель - Проверяйте R² и p-значения, чтобы убедиться, что модель имеет смысл

  5. Используйте последовательный синтаксис - Убедитесь, что спецификация формулы одинакова во всех слоях ggplot2


Полный рабочий пример

Вот полный, исправленный вариант вашего кода:

r
#БИБЛИОТЕКИ
library(tidyverse)
library(ggpubr)
library(ggplot2)

# Создание тестовых данных
test_db <- data.frame(
  X = c(0, -0.1297, -0.2185, -0.2795),
  Y = c(0.7569, 0.7396, 0.6561, 0.5476)
)

# Создание графика с последовательной спецификацией сырых полиномов
test_plot <- ggscatter(test_db, x = "X", y = "Y",
                      xlim = c(-1, 0),
                      ylim = c(0, 1),
                      fill = "red",
                      shape = 23) +
  stat_regline_equation(label.x = -0.95, label.y = 0.15,
                        formula = y ~ poly(x, 2, raw = TRUE),  # Ключевое исправление: raw = TRUE
                        show.legend = FALSE) +
  stat_smooth(method = "lm",
              formula = y ~ poly(x, 2, raw = TRUE),  # Последовательная спецификация
              colour = "black", size = 0.5,
              fill = "red") + 
  theme_bw() + 
  labs(x = "X", y = "Y", title = "Тестовый график с квадратичной регрессией")

# Отображение графика
test_plot

Этот код теперь будет отображать как регрессионную линию, так и уравнение, которые идеально совпадают, поскольку обе функции используют одну и ту же спецификацию сырых полиномов.


Заключение

Расхождение между stat_regline_equation и stat_smooth в вашем коде ggplot2 было вызвано поведением по умолчанию функции poly(), использующей ортогональные полиномы. Установив явно raw = TRUE, вы гарантируете, что обе функции используют один и тот же полиномиальный базис, что приводит к последовательным регрессионным линиям и уравнениям.

Ключевые выводы:

  1. Всегда указывайте raw = TRUE при использовании poly() в регрессионных уравнениях
  2. Обеспечивайте последовательную спецификацию формулы во всех слоях ggplot2
  3. Будьте осведомлены о математических различиях между ортогональными и сырыми полиномами
  4. Учитывайте уместность полиномиальной регрессии для размера вашего набора данных

Это решение решает непосредственную проблему, следуя лучшим практикам для статистической визуализации в R.


Источники

  1. Документация ggpubr stat_regline_equation
  2. Stack Overflow: stat_regline_equation doesn’t match stat_smooth line
  3. Исходный код на GitHub ggpubr - stat_regline_equation.R
  4. RDocumentation: функция stat_regline_equation
  5. Quantargo: ggpubr stat_regline_equation