代码之家  ›  专栏  ›  技术社区  ›  data princess

根据列数,将可变长度字符串作为美学传递给ggplot2

  •  1
  • data princess  · 技术社区  · 6 年前

    我希望能够基于矩阵中的列数构建一个字符串并将其传递给 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_字符串() 产生同样的问题。有没有办法系统地做到这一点?

    1 回复  |  直到 6 年前
        1
  •  0
  •   data princess    6 年前

    你不能跑的原因 parse() eval() 像这样的弦 "axis1 = col1, axis2 = col2" 这是一根绳子吗 一个人 不是有效的R代码。但是整个 ggplot 打电话?可以解析的!

    如果您像这样重新处理plot调用,它将生成很好的冲积图:

    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))