Почему уравнение регрессии из stat_regline_equation не совпадает с линией регрессии из stat_smooth в R?
Я столкнулся с проблемой, при которой создал диаграмму рассеяния с линией квадратичной регрессии с использованием ggplot2 в R. Линия регрессии отображается правильно с помощью stat_smooth(), но уравнение, выводимое stat_regline_equation(), не соответствует этой линии.
Вот код, который я использую:
#БИБЛИОТЕКИ
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()
- Ортогональные vs сырые полиномы
- Различия между stat_smooth и stat_regline_equation
- Решения для устранения расхождения
- Лучшие практики для полиномиальной регрессии в ggplot2
- Полный рабочий пример
Понимание проблемы с функцией 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 сырые полиномы
Давайте проясним ключевое различие:
Ортогональные полиномы (по умолчанию)
poly(x, 2) # По умолчанию использует ортогональные полиномы
- Создает некоррелированные полиномиальные члены
- Лучше для численной стабильности
- Коэффициенты представляют вклады из ортогонализированных членов
- Труднее интерпретировать напрямую
Сырые полиномы
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 (Рекомендуется)
Измените ваш код, чтобы явно использовать сырые полиномы:
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: Использовать сырые полиномиальные члены напрямую
Альтернативный подход - вручную создать полиномиальные члены:
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: Проверить согласованность модели
Вы также можете подогнать модели отдельно, чтобы убедиться, что они идентичны:
# Подогнать модель вручную
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
-
Всегда указывайте raw = TRUE при использовании
poly()в регрессионных уравнениях для обеспечения последовательной интерпретации -
Будьте осторожны с небольшими наборами данных - В вашем примере всего 4 точки данных, квадратичная регрессия может быть переобучена
-
Учитывайте количество параметров - Квадратичная модель с 4 точками данных использует 3 параметра (пересечение, линейный, квадратичный), оставляя только 1 степень свободы
-
Проверяйте вашу модель - Проверяйте R² и p-значения, чтобы убедиться, что модель имеет смысл
-
Используйте последовательный синтаксис - Убедитесь, что спецификация формулы одинакова во всех слоях ggplot2
Полный рабочий пример
Вот полный, исправленный вариант вашего кода:
#БИБЛИОТЕКИ
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, вы гарантируете, что обе функции используют один и тот же полиномиальный базис, что приводит к последовательным регрессионным линиям и уравнениям.
Ключевые выводы:
- Всегда указывайте
raw = TRUEпри использованииpoly()в регрессионных уравнениях - Обеспечивайте последовательную спецификацию формулы во всех слоях ggplot2
- Будьте осведомлены о математических различиях между ортогональными и сырыми полиномами
- Учитывайте уместность полиномиальной регрессии для размера вашего набора данных
Это решение решает непосредственную проблему, следуя лучшим практикам для статистической визуализации в R.