Передайте строку переменной длины в качестве эстетики в ggplot2 на основе количества столбцов - PullRequest
0 голосов
/ 26 июня 2018

Я хотел бы иметь возможность построить строку на основе числа столбцов в моей матрице и передать ее в 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 Ответ

0 голосов
/ 27 июня 2018

Причина, по которой вы не можете запустить 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))
...