Как эффективно создать легенду вручную при использовании цикла для создания нескольких объектов geom_hline в фасете?

Я написал приведенный ниже пример, чтобы проиллюстрировать мой вопрос.

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

Тем не менее, я создаю функцию, которая будет создавать любое количество горизонтальных линий на графике с помощью цикла. Это означает, что мне нужно было динамически передавать переменные в функцию aes_string. Тем не мение, aes_string(yintercept = colname, colour = colname) не работает. как я получил бы следующую ошибку'geom_hline Error: Discrete value supplied to continuous scale',

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

Это работает как задумано, но у меня есть 2 вопроса:

  1. Почему aes_string(yintercept = colname, colour = colname_colour) работа и aes_string(yintercept = colname, colour = colname) не.

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

вывод примера кода: https://imgur.com/a/dvzAM

mean_wt <- data.frame(cyl = c(4, 6, 8)
, wt = c(2.28, 3.11, 4.00)
, wt2 = c(3.28, 4.11, 5.00)
, wt_col = c("a", "a", "a")
, wt_col2 = c("b", "b", "b"))

hline_listA <- list()
for(i in 2:3){
  colname <- mean_wt[,i]
  colname_colour <- mean_wt[,i+2]
  grob <- geom_hline(data =mean_wt
, aes_string(yintercept = colname, colour = colname_colour) )
  hline_listA[[i-1]] <- grob
}
ggplot() +
  geom_point(data = mtcars, aes(mpg, wt)) +
  hline_listA +
  facet_wrap(~ cyl, scales = "free", nrow = 1) +
  scale_colour_manual(name = "legend", values = c( 
    "a" = "seagreen1"  
    , "b" = "darkorange" ))

1 ответ

Решение

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

library(ggplot2)
mean_wt <- data.frame(cyl = c(4, 6, 8), 
                      wt = c(2.28, 3.11, 4.00, 3.28, 4.11, 5.00),
                      wt_col = c("a", "a", "a", "b", "b", "b"))

ggplot() +
  geom_point(data = mtcars, aes(mpg, wt)) +
  geom_hline(data = mean_wt,aes(yintercept = wt, color = wt_col)) +
  facet_wrap(~ cyl, scales = "free", nrow = 1) +
  scale_colour_manual(name = "legend", 
                      values = c("a" = "seagreen1",
                                 "b" = "darkorange" ))

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

Другие вопросы по тегам