ggplot: маркировка значений geom_smooth / stat_smooth правильным значением

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

См. пример ниже для проблемы:

require(tidyverse)
require(ggrepel)

set.seed(1)
df <- data.frame(x = rep(1:100, 5), y = c(sample(1:20, 100, T), sample(21:40, 100, T), sample(41:60, 100, T), sample(61:80, 100, T), sample(81:100, 100, T)), group = rep(letters[1:5], each = 100))
df <- tbl_df(df)

df %>% 
  ggplot(aes(x = x, y = y, label = group, color = group)) + 
  geom_smooth() +
  guides(color = F) +
  geom_text_repel(data = . %>% filter(x == max(x)), aes(x = x, y = y, label = group), nudge_x = 50)

Неверные метки

Есть ли способ получить значение гладкой линии в max(x) без использования ggplot_build() или другого внешнего многошагового подхода?


person jzadra    schedule 07.08.2017    source источник


Ответы (1)


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

library(broom)

df %>%
  {ggplot(., aes(x, y, label = group, color = group)) + 
  geom_smooth() + 
  guides(color = F) +
  geom_text(data = group_by(., group) %>% 
                    do(augment(loess(y~x, .))) %>% 
                    filter(x == max(x)),
            aes(x, .fitted), nudge_x = 5)}

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

Вам нужно сделать прогноз лёсса более гладким при этом конечном значении x, так что вам просто нужно подогнать его дважды. Если подгонка модели идет медленно, вы можете сделать это один раз, выше в цепочке dplyr, и просто использовать вывод для остальной части рисунка.

df %>%
  group_by(group) %>% 
  do(augment(loess(y~x, .))) %>% 
  {ggplot(., aes(x, y, label = group, color = group)) + 
  geom_smooth() + 
  guides(color = F) +
  geom_text(data = filter(., x == max(x)),
            aes(x, .fitted), nudge_x = 5)}
person Brian    schedule 08.08.2017