`geom_smooth` с полиномом переменной степени в формуле

У меня есть следующий код ggplot2 который отображает несколько полиномов с различными степенями:

library(ggplot2)

set.seed(1234)
n = 400
x = rnorm(n, sd=0.4)
y = -x + 2*x^2 - 3*x^3 + rnorm(n,sd=0.75)
df = data.frame(x=x,y=y)

deg = c(1,2,3,10)
cols = c("red","green","blue","orange")
ggplot(df, aes(x=x,y=y)) + 
  geom_point() + 
  geom_smooth(method = "lm", formula= y~poly(x,deg[1]), se=F, col=cols[1]) +
  geom_smooth(method = "lm", formula= y~poly(x,deg[2]), se=F, col=cols[2]) +
  geom_smooth(method = "lm", formula= y~poly(x,deg[3]), se=F, col=cols[3]) +
  geom_smooth(method = "lm", formula= y~poly(x,deg[4]), se=F, col=cols[4]) 

Я хотел бы избежать повторения строки geom_smooth для каждого градуса. Но я не могу понять, как заставить geom_smooth понимать динамическую степень, передаваемую через переменную. Есть ли более элегантное решение для вышеперечисленного? Было бы неплохо также автоматически менять цвета без необходимости явно передавать вектор cols . (Цветовая схема по умолчанию в порядке).

Я попытался использовать as.formula(paste0("y~poly(x,",deg[i],")")) через цикл без особой удачи (и циклы не кажутся правильным подходом с ggplot .)

Всего 1 ответ


Вы можете добавить список элементов plot в ggplot, чтобы использовать map для создания списка из четырех вызовов geom_smooth , по одному для каждого градуса в deg .

library(tidyverse)

ggplot(df, aes(x=x,y=y)) + 
  geom_point() +
  map(1:length(deg), 
      ~geom_smooth(method="lm", formula=y~poly(x, deg[.x]), se=F, col=cols[.x]))

Вы также можете добавить легенду, если хотите. Например:

ggplot(df, aes(x=x,y=y)) + 
  geom_point(colour="grey60") +
  map(1:length(deg), 
      ~geom_smooth(method="lm", formula=y~poly(x, deg[.x]), se=F,
                   aes(color=factor(deg[.x])))) + 
  scale_colour_manual(name="Degree", breaks=deg, values=set_names(cols, deg)) +
  theme_bw() +
  theme(legend.text.align=1)

введите описание изображения здесь

Если вас устраивают цвета по умолчанию, измените строку scale_colour_manual на:

scale_colour_discrete(name="Degree", breaks=deg) +

Есть идеи?

10000