Как использовать переменную для указания имени столбца в ggplot
У меня есть команда ggplot
ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )
внутри функции. Но я хотел бы иметь возможность использовать параметр функции для выбора столбца для использования в качестве цвета и группы. То есть Мне хотелось бы что-то вроде этого
f <- function( column ) {
...
ggplot( rates.by.groups, aes(x=name, y=rate, colour= ??? , group=??? ) )
}
Итак, столбец, используемый в ggplot, определяется параметром. Например. для f ( "majr" ) получаем эффект
ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )
но для f ( "пол" ) мы получаем эффект
ggplot( rates.by.groups, aes(x=name, y=rate, colour=gender, group=gender) )
Некоторые вещи, которые я пробовал:
ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ) )
не работает. Не
e <- environment()
ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ), environment=e )
Ответы
Ответ 1
Вы можете использовать aes_string
:
f <- function( column ) {
...
ggplot( rates.by.groups, aes_string(x="name", y="rate", colour= column,
group=column ) )
}
пока вы передаете столбец функции как строку (f("majr")
, а не f(majr)
). Также обратите внимание, что мы изменили другие столбцы, "name"
и "rate"
, чтобы быть строками.
Если по какой-либо причине вы предпочитаете не использовать aes_string
, вы можете изменить его на (несколько более громоздкий):
ggplot( rates.by.groups, aes(x=name, y=rate, colour= get(column),
group=get(column) ) )
Ответ 2
Из примечаний к выпуску ggplot2 V3.0.0
:
aes() теперь поддерживает квазиквотацию, так что вы можете использовать !!, !!! и: =. Это заменяет aes_() и aes_string(), которые теперь мягко осуждаются (но останутся в течение долгого времени).
Теперь идиоматическим способом было бы преобразовать в символ строку, содержащуюся в переменной, используя sym
(что почти совпадает с базовыми псевдонимами as.name
/as.symbol
), и заключить ее в кавычки, используя !!
Имитацию данных OP мы можем сделать:
library(tidyverse)
rates.by.groups <- data.frame(
name = LETTERS[1:3],
rate = 1:3,
mjr = LETTERS[c(4,4,5)],
gender = c("M","F","F")
)
f <- function(column) {
column <- sym(column)
ggplot(rates.by.groups,
aes(x = name,
y = rate,
fill = !!column,
group = !!column)) +
geom_col()
}
f("gender")
f("mjr")
x <- "gender"
f(x)
Если бы мы предпочли передать необработанные имена в функцию, которую мы можем сделать:
f2 <- function(column) {
column <- ensym(column)
ggplot(rates.by.groups,
aes(x = name,
y = rate,
fill = !!column,
group = !!column)) +
geom_col()
}
Он будет работать с именами или символами AND и со строковыми литералами
f2(gender)
f2(mjr)
f2("gender")
f2("mjr")
Как говорит Лайонел о ensym
:
это имитировало синтаксис аргументов, где вы можете указывать оба в LHS, например, list (bare = 1, "quoted" = 2)
Заметка на enquo
enquo
кавычки выражение (не обязательно символ), enquo
в аргумент, оно не преобразует строковый литерал в символ, как ensym
делает ensym
, поэтому оно может быть менее адаптировано здесь, но мы можем сделать:
f3 <- function(column) {
column <- enquo(column)
ggplot(rates.by.groups,
aes(x = name,
y = rate,
fill = !!column,
group = !!column)) +
geom_col()
}
f3(gender)
f2(mjr)
Ответ 3
Попробуйте использовать aes_string
вместо aes
.
Ответ 4
Другой вариант (ggplot2 > 3.0.0
) - использовать местоимение аккуратной оценки .data
чтобы rates.by.groups
выбранную переменную/столбец из rates.by.groups
данных rates.by.groups
.
library(ggplot2)
theme_set(theme_classic(base_size = 14))
# created by @Moody_Mudskipper
rates.by.groups <- data.frame(
name = LETTERS[1:3],
rate = 1:3,
mjr = LETTERS[c(4, 4, 5)],
gender = c("M", "F", "F")
)
f1 <- function(df, column) {
gg <- ggplot(df,
aes(x = name,
y = rate,
fill = .data[[column]],
group = .data[[column]])) +
geom_col() +
labs(fill = column)
return(gg)
}
plot_list <- lapply(list("gender", "mjr"), function(x){ f1(rates.by.groups, x) })
plot_list
#> [[1]]
![]()
#>
#> [[2]]
![]()
# combine all plots
library(egg)
ggarrange(plots = plot_list,
nrow = 2,
labels = c('A)', 'B)'))
![]()
Создано 2019-04-04 пакетом представлением (v0.2.1.9000)