#r #ggplot2
#r #ggplot2
Вопрос:
В настоящее время я пытаюсь разобраться в различиях между stat_*
и geom_*
в ggplot2
. (Пожалуйста, обратите внимание, что это скорее вопрос, основанный на интересе / понимании, чем на конкретной проблеме, которую я пытаюсь решить).
Введение
Мое текущее понимание заключается в том, что stat_*
функции применяют преобразование к вашим данным и что результат затем передается на geom_*
для отображения.
Самым простым примером является преобразование идентификатора, которое просто передает ваши данные в нетрансформированном виде в geom.
ggplot(data = iris)
stat_identity(aes(x = Sepal.Length, y = Sepal.Width) , geom= "point")
Более практичные варианты использования, по-видимому, заключаются в том, что вы хотите использовать некоторое преобразование и предоставить результаты в геометрию, отличную от геометрии по умолчанию, например, если вы хотите отобразить панель ошибок 1-го и 3-го квартилей, вы могли бы сделать что-то вроде:
ggplot(data = iris)
stat_boxplot(aes(x=Species, y = Sepal.Length, ymax = ..upper.., ymin = ..lower..), geom = "errorbar")
Вопрос 1
Итак, как / когда эти преобразования применяются к набору данных и как именно данные проходят через них?
В качестве примера, скажем, я хотел провести stat_boxplot
преобразование и построить точку 3-го квартиля, как бы я это сделал?
Моя интуиция была бы чем-то вроде :
ggplot(data = iris)
stat_boxplot(aes(x=Species, y = ..upper..) , geom = "point")
или
ggplot(data = iris)
stat_boxplot(aes(x=Species, y = Sepal.Length) , geom = "point")
однако обе ошибки с
Error: geom_point requires the following missing aesthetics: y
Я предполагаю, что в рамках stat_boxplot
преобразования он использует эстетику y и создает набор данных, не содержащий какой-либо y
переменной, однако это приводит к ….
Вопрос 2
Где я могу узнать, какие переменные используются как часть stat_*
преобразования и какие переменные они выводят? Возможно, я ищу не в тех местах, но документация мне совсем не кажется понятной…
Комментарии:
1. Я не могу протестировать прямо сейчас, но я считаю, что вам нужно вызвать geom_point и передать stat_boxplot в его аргумент stat. Причина в том, что вам нужно передать x и y в aes geom_point, а ваш подход передает их в aes stat_boxplot.
2. Я не думаю, что это что-то изменит, извините, потому что оба
stat_*
иgeom_*
являются просто оболочками дляlayer()
функции, но с фиксированными значениями аргументовstat
иgeom
. Поэтому я думаю, что простое переключение наgeom_point()
все равно приведет к тому же вызовуlayer()
. Тем не менее, спасибо за ваш комментарий!3. Вы пробовали?
4. Я сделал —
ggplot(data = iris) geom_point( aes(x=Species, y = Sepal.Length), stat = "boxplot")
приводит к тому же сообщению об ошибкеError: geom_point requires the following missing aesthetics: y
🙁
Ответ №1:
Интересные вопросы…
В качестве справочной информации вы можете прочитать эту главу R for Data Science, посвященную грамматике графики. Я уверен, что книга Хэдли Уикхема о ggplot2 — еще лучший источник, но у меня его нет.
Основными шагами для построения графика с одним слоем и без фасета являются:
- Примените эстетическое отображение к входным данным (в простых случаях это выделение и переименование столбцов)
- Примените масштабное преобразование (если таковое имеется) к каждому столбцу данных
- Вычислите статистику для каждой группы данных (т. Е. для каждого вида в данном случае)
- Применить отображение эстетики к статистическим данным, обнаруженным с помощью
..<name>..
илиstat(name)
- Применить корректировку положения
- Построение графических объектов
- Примените преобразования координат
Как вы догадались, поведение на шаге 3 аналогично dplyr::transmute()
: оно использует все столбцы эстетики и выводит фрейм данных, содержащий в качестве столбцов все недавно вычисленные статистические данные и все столбцы, которые являются постоянными в группе. Вывод статистики также может иметь другое количество строк, чем на входе. Таким образом, действительно, в вашем примере y
столбец не передается в геометрию.
Для этого мы хотели бы указать различные сопоставления на шаге 1 (перед stat) и на шаге 4 (перед geom). Я думал, что что-то подобное сработает:
# This does not work:
ggplot(data = iris)
geom_point(
aes(x=Species, y=stat(upper)),
stat=stat_boxplot(aes(x=Species, y=Sepal.Length)) )
… но это не так (stat должен быть строкой или объектом Stat, но stat_boxplot фактически возвращает объект слоя, как это делает geom_point).
ПРИМЕЧАНИЕ: stat(upper)
является ли эквивалентная, более свежая, запись вашей ..upper..
Возможно, я ошибаюсь, но я не думаю, что есть способ сделать это непосредственно в ggplot. Что вы можете сделать, так это извлечь статистическую часть процесса выше и управлять ею самостоятельно, прежде чем вводить ggplot():
library(tidyverse)
iris %>%
group_by(Species) %>%
select(y=Sepal.Length) %>%
do(StatBoxplot$compute_group(.)) %>%
ggplot(aes(Species, upper)) geom_point()
Признаю, немного менее элегантно…
Что касается вашего вопроса 2, он находится в документе: см. Разделы Эстетика и вычисляемые переменные ?stat_boxplot
Комментарии:
1. @gowerc, это тот ответ, который вы ожидали?