如何减少 Tidyverse 代码的多行重复行 - 对于具有不同 Y 的 X 的多个图表 - 使用名称向量

How to Reduce Multiple Repeating Lines of Tidyverse Code - for Multiple Charts with X by Different Y's - Using a Vector of Names

library(tidyverse) 

使用 Iris 数据集,下面的代码使用 tidyverse 方法创建多个图表,最终是我想要实现的。但是,写出 "gg1"、"gg2" 和 "gg3" 这三行似乎是重复的,所以我试图以更有效的方式重写它。 (见下面的代码)

iris0 <- iris %>%  
group_by(Species) %>%  
nest() %>%  
mutate(
gg1 = map(data, ~ ggplot(., aes(Sepal.Length, Sepal.Width)) + geom_point()),
gg2 = map(data, ~ ggplot(., aes(Sepal.Length, Petal.Width)) + geom_point()),
gg3 = map(data, ~ ggplot(., aes(Sepal.Length, Petal.Length)) + geom_point()),
g = pmap(list(gg1, gg2, gg3), ~ gridExtra::grid.arrange(..1, ..2, ..3))
)

暂时忽略最后的 gridExtra 部分以及名称(gg1、gg2 和 gg3),下面是尝试使用名称向量从上面的代码在一行代码中生成三个图表称为Y。但这似乎不起作用。我尝试了其他一些变体,但希望能提供帮助...

Y<-c("Sepal.Width","Petal.Width","Petal.Length")

iris0<-iris%>%
group_by(Species)%>%
nest()%>%
mutate(
   map(data,~ggplot(.,aes(Sepal.Length))+geom_point(aes_string(Y))))

我认为重塑和使用不同的分组变量可能是这里更容易遵循的方法,但您可以尝试使用双 map 循环遍历每个物种的当前正在使用的行和每个 y 变量。

映射到 geom_point 中的 y 美学时,不要忘记定义 y 参数。这将至少避免您现在遇到的一些错误。

我包含用于将图表发送到 grid.arrange 的代码。

iris %>%
     group_by(Species) %>%
     nest() %>%
     mutate(graphs = map(data, function(x) {
               map(Y, function(y) ggplot(x, aes(Sepal.Length )) +
                                       geom_point( aes_string(y = y) ) )
               }),
          grid.graphs = map(graphs, ~gridExtra::grid.arrange(grobs = .x) ) )

您可以使用 top 参数将物种名称添加到多图,但我必须将嵌套数据集分组才能工作。

iris %>%
    group_by(Species) %>%
    nest() %>%
    group_by(Species) %>%
    mutate(graphs = map(data, function(x) {
        map(Y, function(y) ggplot(x, aes(Sepal.Length )) +
                geom_point( aes_string(y = y) ) )
    }),
    grid.graphs = map(graphs, ~gridExtra::grid.arrange(grobs = .x, 
                                                       top = grid::textGrob(Species) ) ) )

我发现嵌套循环相对难以遵循。重塑方法需要更多的代码,所以最终看起来非常复杂。本质上你让你的数据集变长,然后在绘制图之前对两个物种和 y 变量 nest

我最后为 grid.arrange 做了第二个嵌套,这看起来很复杂。

iris %>%
     gather(variable, yvar, one_of(Y) ) %>%
     group_by(Species, variable) %>%
     nest() %>%
     group_by(Species, variable) %>%
     mutate(graphs = map(data, ~ggplot(.x, aes(Sepal.Length, yvar) ) +
                              geom_point() +
                              labs(y = unique(variable) ) ) ) %>%
     group_by(Species) %>%
     nest(graphs, .key = "graphs") %>%
     mutate(grid.graphs = map(graphs, ~gridExtra::grid.arrange(grobs = flatten(.x)) ) )