Передайте строку переменной длины в качестве эстетики в 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))
Другие вопросы по тегам