Как я могу получить пик и впадины линии geom_smooth в ggplot2?

#r #ggplot2

#r #ggplot2

Вопрос:

Я строю некоторые данные за год, и мне нужно получить пики и впадины кривой, а не из набора данных, а затем определить, какая из них соответствует этой дате. Как я могу это сделать?

 g <- ggplot(df, aes(x=date, y=ndvitrend))   geom_point()   geom_smooth(method = "gam", se=FALSE)   theme_minimal()  
     scale_x_date(date_labels="%b %Y", date_breaks = "1 month")   
     theme(plot.title = element_text(hjust = 0.5))   theme(axis.line = element_line(color = 'black'))  
     theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))   
     stat_peaks(span=NULL, color="red")
  

пик набора данных, а не на линии

Спасибо

Ответ №1:

Гораздо проще ответить на этот вопрос, если у нас есть воспроизводимые данные. Тем не менее, я воссоздам что-то похожее на ваш набор данных:

 set.seed(69)

df <- data.frame(date = seq(as.Date("2019-09-01"), 
                            as.Date("2020-09-01"), by = "3 days"),
                 ndvitrend = 0.3 * sin(seq(-2, 2 * pi - 2, length.out = 123))  
                             rnorm(123, 0.5, 0.2))
  

Теперь давайте построим это, используя ваш код:

 library(ggpmisc)

g <- ggplot(df, aes(x = date, y = ndvitrend))   
      geom_point()   
      geom_smooth(method = "gam", se = FALSE)   
      stat_peaks(span = NULL, color = "red")  
      theme_minimal()  
      scale_x_date(date_labels = "%b %Y", date_breaks = "1 month")   
      theme(plot.title  = element_text(hjust = 0.5),
            axis.line   = element_line(color = 'black'),
            axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))
g
#> `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
  

Вы заметите, что консоль сообщила нам формулу, которая использовалась для создания сглаженной линии. Поэтому мы можем использовать это, чтобы ответить на ваш вопрос. Нам нужна gam функция из package mgcv :

 library(mgcv)

df$days <- as.numeric(difftime(df$date, df$date[1], units = "day"))
model   <- gam(ndvitrend ~ s(days, bs = "cs"), data = df)
df$prediction <- predict(model)
  

Итак, теперь мы сохранили прогнозы из этой модели в нашем фрейме данных. Это должно дать нам идентичную кривую сглаживания, которая geom_smooth дала нам:

 g   geom_line(aes(y = prediction), data = df, 
                   size = 3, linetype = 2, col = "red")
#> `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
  

Это правильно. Теперь все, что нам нужно сделать, это выяснить, где был пик нашего прогноза:

 g   geom_hline(yintercept = max(df$prediction), linetype = 2)
#> `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
  

Итак, мы видим, что наш сглаженный пик в этом наборе данных равен

 max(df$prediction)
#> [1] 0.76714
  

И это происходит на:

 df$date[which.max(df$prediction)]
#> [1] "2020-03-20"
  

Создано 2020-09-18 пакетом reprex (версия 0.3.0)