r - 在ggplot中循环变量

标签 r for-loop ggplot2 tidyeval nse

我想使用 ggplot 循环遍历多个列以创建多个图,但是在 for 循环中使用占位符会改变 ggplot 的行为。

如果我有这个:

t <- data.frame(w = c(1, 2, 3, 4), x = c(23,45,23, 34), 
y = c(23,34,54, 23), z = c(23,12,54, 32))

这工作正常:
ggplot(data=t, aes(w, x)) + geom_line()

但这不会:
i <- 'x'
ggplot(data=t, aes(w, i)) + geom_line()

如果我想最终遍历 x、y 和 z,这是一个问题。
有什么帮助吗?

最佳答案

ggplot2 > 3.0.0 支持整洁的评价代词 .data .所以我们可以做到以下几点:

  • 构建一个将 x- 和 y- 列名称作为输入的函数。注意 .data[[]] 的使用.
  • 然后使用 purrr::map 遍历每一列.

  • library(rlang)
    library(tidyverse)
    
    dt <- data.frame(
      w = c(1, 2, 3, 4), x = c(23, 45, 23, 34),
      y = c(23, 34, 54, 23), z = c(23, 12, 54, 32)
    )
    
    定义一个接受字符串作为输入的函数
    plot_for_loop <- function(df, x_var, y_var) {
      
      ggplot(df, aes(x = .data[[x_var]], y = .data[[y_var]])) + 
        geom_point() + 
        geom_line() +
        labs(x = x_var, y = y_var) +
        theme_classic(base_size = 12)
    }
    
    循环遍历每一列
    plot_list <- colnames(dt)[-1] %>% 
      map( ~ plot_for_loop(dt, colnames(dt)[1], .x))
    
    # view all plots individually (not shown)
    plot_list
    
    # Combine all plots
    library(cowplot)
    plot_grid(plotlist = plot_list,
              ncol = 3)
    

    编辑 : 上面的函数也可以写成 rlang::sym & !! (嘭嘭)。
    plot_for_loop2 <- function(df, .x_var, .y_var) {
      
      # convert strings to variable
      x_var <- sym(.x_var)
      y_var <- sym(.y_var)
      
      # unquote variables using !! 
      ggplot(df, aes(x = !! x_var, y = !! y_var)) + 
        geom_point() + 
        geom_line() +
        labs(x = x_var, y = y_var) +
        theme_classic(base_size = 12)
    }
    
    或者我们可以使用 facet_grid / facet_wrap 将数据帧从宽格式转换为长格式后( tidyr::gather )

    dt_long <- dt %>% 
      tidyr::gather(key, value, -w)
    dt_long
    #>    w key value
    #> 1  1   x    23
    #> 2  2   x    45
    #> 3  3   x    23
    #> 4  4   x    34
    #> 5  1   y    23
    #> 6  2   y    34
    #> 7  3   y    54
    #> 8  4   y    23
    #> 9  1   z    23
    #> 10 2   z    12
    #> 11 3   z    54
    #> 12 4   z    32
    
    ### facet_grid
    ggp1 <- ggplot(dt_long, 
           aes(x = w, y = value, color = key, group = key)) +
      facet_grid(. ~ key, scales = "free", space = "free") +
      geom_point() + 
      geom_line() +
      theme_bw(base_size = 14)
    ggp1
    

    ### facet_wrap
    ggp2 <- ggplot(dt_long, 
           aes(x = w, y = value, color = key, group = key)) +
      facet_wrap(. ~ key, nrow = 2, ncol = 2) +
      geom_point() + 
      geom_line() +
      theme_bw(base_size = 14)
    ggp2
    

    ### bonus: reposition legend
    # https://cran.r-project.org/web/packages/lemon/vignettes/legends.html
    library(lemon)
    reposition_legend(ggp2 + theme(legend.direction = 'horizontal'), 
                      'center', panel = 'panel-2-2')
    

    关于r - 在ggplot中循环变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4856849/

    相关文章:

    r - 更改箱线图的布局并为其添加标签

    r - 将值从一个数据帧传输到另一个数据帧

    r - 在 R 中的两个数字之间,即 5<=R>7

    r - 将小数截断到指定位置

    python - 日期范围匹配函数 pandas

    r - 在 ggpmisc 和 ggplot 中使用 stat_fit_tb() 时编辑表格显示的*行*名称

    r - 使用 ggplot2 对齐子集数据点

    R:将列表的列表的列表写入带有名称的文本文件

    Java:简单的数组分割程序

    Python循环遍历列表并根据条件追加