Передайте строку переменной длины в качестве эстетики в ggplot2 на основе количества столбцов
Я хотел бы иметь возможность построить строку на основе количества столбцов в моей матрице и передать ее ggplot
как эстетическое. Это не покрывается aes_string()
функция. Причина, по которой я хочу, это то, что я использую ggalluvial
пакет, но тонкости имеют меньшее значение, чем принцип. Мой код выглядит так:
library(ggplot2)
library(ggalluvial)
my_alluvial_plot <- function(scores, n_groups = 5) {
score_names <- names(scores)
scr_mat <- data.matrix(scores)
n_cols <- ncol(scores)
# create ntiles of scores so that flow can be seen between groups
ranks <- apply(scr_mat, 2, function(x) {
rk <- dplyr::ntile(x, n_groups)
return(as.factor(rk))
})
to_plot <- data.frame(ranks)
# build the string for the aes() function
a_string <- ""
for (i in 1:n_cols) {
a_string <- paste0(a_string, "axis", i, " = to_plot[, ", i, "],")
}
# remove final comma
a_string <- substr(a_string, 1, nchar(a_string) - 1)
ggplot(to_plot,
aes(eval(a_string))) +
geom_alluvium(aes(fill = to_plot[, n_cols], width = 1/12)) +
geom_stratum(width = 1/12, fill = "black", color = "grey") +
scale_x_continuous(breaks = 1:n_cols, labels = score_names) +
scale_fill_brewer(type = "qual", palette = "Set1")
}
df <- data.frame(col1 = runif(10),
col2 = runif(10),
col3 = rnorm(10),
col4 = rnorm(10))
my_alluvial_plot(df)
Это создает пустой график со следующей ошибкой:
Warning: Ignoring unknown aesthetics: width
Error: Discrete value supplied to continuous scale
По сути, я хочу построить аллювиальный график, который может поддерживать произвольное количество столбцов, поэтому код ggplot в его оценке будет выглядеть как
ggplot(to_plot,
aes(axis1 = data[, 1], axis2 = data[, 2], axis3 = data[, 3], ...))
Но ни eval()
или же parse()
произвести что-нибудь разумное. aes_string()
производит ту же проблему. Есть ли способ сделать это систематически?
1 ответ
Причина, по которой вы не можете бежать parse()
или же eval()
на струнах, как "axis1 = col1, axis2 = col2"
является то, что такая строка сама по себе не является допустимым кодом R. Но весь ggplot
вызов? Это можно разобрать!
Если вы переделываете вызов заговора следующим образом, он прекрасно создает аллювиальный заговор:
gg_string <- paste0("ggplot(to_plot,
aes(", a_string, ")) +
geom_alluvium(aes(fill = to_plot[, n_cols], width = 1/12)) +
geom_stratum(width = 1/12, fill = 'black', color = 'grey') +
scale_x_continuous(breaks = 1:n_cols, labels = score_names) +
scale_fill_brewer(type = 'qual', palette = 'Set1')")
eval(parse(text = gg_string))