使用 ggplot2 针对另一组绘制一组列

plot one set of columns against another set using ggplot2

ggplot2 能否用于创建一组列与另一组列的绘图矩阵?

例如,使用下面的数据框绘制所有以 'x' 开头的列与所有以 'y' 开头的列,以生成绘图网格。

require("tidyverse")

df <- tibble(
  x1 = sample(10),
  x2 = sample(10),
  x3 = sample(10),
  y1 = sample(10),
  y2 = sample(10)
)

如果与上面的示例不同,列没有以常规模式命名怎么办 - 有没有办法可以选择任意组的列?

提前致谢

最简单的方法可能是遍历所有可能的组合,绘制相应的图,然后将所有组合成一个网格。

require("tidyverse")

df <- tibble(
  x1 = sample(10),
  x2 = sample(10),
  x3 = sample(10),
  y1 = sample(10),
  y2 = sample(10)
)


group1 <- c("x1", "x2", "x3") # set of variables along x axis
group2 <- c("y1", "y2") # set of variables along y axis

plotlist <- list()
for (x in group1) {
  for (y in group2) {
    p <- ggplot(df, aes_string(x, y)) + geom_point() + ggtitle(paste0(y, " versus ", x))
    plotlist <- append(plotlist, list(p))
  }
}

cowplot::plot_grid(plotlist = plotlist)

此处的最后一步使用我编写的 cowplot 包。或者,您可以使用 egg 包中的 ggarrange 将绘图放入网格中。

您可以使用 tidyr::gather 然后 facet:

重塑
df_long <- df %>% 
  gather(x_axis, x, contains("x")) %>% 
  gather(y_axis, y, contains("y"))
# A tibble: 60 x 4
   x_axis     x y_axis     y
    <chr> <int>  <chr> <int>
 1     x1    10     y1     6
 2     x1     6     y1    10
 3     x1     5     y1     3
 4     x1     7     y1     8
 5     x1     8     y1     2
 6     x1     1     y1     1
 7     x1     3     y1     5
 8     x1     9     y1     9
 9     x1     4     y1     7
10     x1     2     y1     4
# ... with 50 more rows

您可以使用任何其他 tidyverse 选择函数代替 contains,或者只提供原始列名。

然后剧情:

ggplot(df_long, aes(x, y)) + 
    geom_point() + 
    facet_grid(y_axis ~ x_axis, switch = "both") +
    labs(x = NULL, y = NULL) +
    theme(strip.placement = "outside", strip.background = element_blank())

如果你需要自由秤,你可以用包裹代替:

ggplot(df_long, aes(x, y)) + 
    geom_point() + 
    facet_wrap(~ interaction(y_axis, x_axis), scales = "free")

为了完整起见,这里有一个使用 GGally 包中的 ggduo 的解决方案(我刚刚意识到的一个功能)

require(GGally)    
df %>% ggduo(columnsX = 1:3, columnsY = 4:5)