#r #ggplot2 #density-plot #facet-grid #dollar-sign
#r #ggplot2 #r-faq
Вопрос:
В данный момент я провожу некоторый анализ в ggplot2 для проекта, и случайно я наткнулся на какое-то (для меня) странное поведение, которое я не могу объяснить. Когда я пишу aes(x = cyl, ...)
, график выглядит иначе, чем при передаче той же переменной с использованием aes(x = mtcars$cyl, ...)
. Когда я удаляю facet_grid(am ~ .)
оба графика, они снова становятся одинаковыми. Приведенный ниже код смоделирован после кода в моем проекте, который генерирует такое же поведение:
library(dplyr)
library(ggplot2)
data = mtcars
test.data = data %>%
select(-hp)
ggplot(test.data, aes(x = test.data$cyl, y = mpg))
geom_point()
facet_grid(am ~ .)
labs(title="graph 1 - dollar sign notation")
ggplot(test.data, aes(x = cyl, y = mpg))
geom_point()
facet_grid(am ~ .)
labs(title="graph 2 - no dollar sign notation")
Вот изображение графика 1:
Вот изображение графика 2:
Я обнаружил, что могу обойти эту проблему, используя aes_string
вместо aes
и передавая имена переменных в виде строк, но я хотел бы понять, почему ggplot ведет себя таким образом. Проблема также возникает при аналогичных попытках с facet_wrap
.
Комментарии:
1. короткий ответ: никогда не используйте
$
вaes()
2. ^_^ после шока, который я испытал сегодня, когда мой график внезапно стал выглядеть странно, я больше не буду этого делать. Тем не менее, я хотел бы понять, что происходит, потому что я никогда раньше не сталкивался с этой проблемой / поведением.
3. когда ggplot строит график, if разбивает наборы данных для каждого слоя на группы, определяемые эстетикой и фасетированием. Чтобы эта группировка была надежной, вам нужно, чтобы переменные происходили из одного data.frame , иначе ggplot может в конечном итоге использовать другой порядок для коэффициента фасетирования и остальной части отображения.
4. хм, но разве переменная не находится в том же data.frame в этом примере, независимо от того, пишу ли я aes(x = cyl, …) или aes(x = test.data $ cyl, …)? тест. данные — это data.frame, который я передаю в ggplot, и он содержит все переменные. Где я ошибаюсь? Большое спасибо за ваш быстрый ответ!
5. Дело в том, что, поскольку ggplot использует нестандартные методы оценки, а среда R и системы определения области видимости могут быть сложными, при использовании $ here вы предоставляете потенциально запутанную информацию, которая заставит ggplot реагировать непредсказуемо. Способы, при которых что-то может пойти не так, разнообразны, сложны и обычно неинтуитивны.
Ответ №1:
tl; dr
Никогда не используйте [
или $
внутри aes()
.
Рассмотрим этот иллюстративный пример, в котором переменная f
фасетирования намеренно находится в неочевидном порядке относительно x
d <- data.frame(x=1:10, f=rev(letters[gl(2,5)]))
Теперь сравните, что происходит с этими двумя графиками,
p1 <- ggplot(d)
facet_grid(.~f, labeller = label_both)
geom_text(aes(x, y=0, label=x, colour=f))
ggtitle("good mapping")
p2 <- ggplot(d)
facet_grid(.~f, labeller = label_both)
geom_text(aes(d$x, y=0, label=x, colour=f))
ggtitle("$ corruption")
Мы можем получить лучшее представление о том, что происходит, посмотрев на data.frame, созданный внутри ggplot2 для каждой панели,
ggplot_build(p1)[["data"]][[1]][,c("x","PANEL")]
x PANEL
1 6 1
2 7 1
3 8 1
4 9 1
5 10 1
6 1 2
7 2 2
8 3 2
9 4 2
10 5 2
ggplot_build(p2)[["data"]][[1]][,c("x", "PANEL")]
x PANEL
1 1 1
2 2 1
3 3 1
4 4 1
5 5 1
6 6 2
7 7 2
8 8 2
9 9 2
10 10 2
Второй график имеет неправильное отображение, потому что, когда ggplot создает data.frame для каждой панели, он выбирает значения x в «неправильном» порядке.
Это происходит потому, что использование $
разрывает связь между различными отображаемыми переменными (ggplot должен предполагать, что это независимая переменная, которая, насколько ему известно, может поступать из произвольного, отключенного источника). Поскольку data.frame в этом примере не упорядочен в соответствии с фактором f
, подмножество data.frames, используемое внутри для каждой панели, принимает неправильный порядок.
Комментарии:
1. Большое спасибо за вашу помощь! Ваш пример потрясающий!
2. Эта проблема была исправлена в
ggplot2 v3.0.0.9000