dplyr在匿名函数中执行多个绘图

时间:2018-10-05 15:09:12

标签: r ggplot2 dplyr

我想使用do根据分组的数据帧制作多个ggplots,但要更改图,即如果一列包含特定值,则反转y轴。

我以哈德利(Hadley)对以下问题的回答为模型:dplyr::do() requires named function?

我遇到的问题是将gg对象放入数据框以返回它,如何在下面的工作示例中手动do自动执行操作,然后将gg对象“包装”在可以放在数据框中?

df <-   data.frame( position=rep(seq(0,99),2),
                    strand=c(rep("-",100),rep("+",100)),
                    score=rnorm(200),
                    gene=c(rep("alpha",100),rep("beta",100))
        )

这很好:

plots <- df %>% 
    group_by(gene) %>%
    do(plot=
        ggplot(.,aes(position,score)) +
            geom_point()
    )
plots   

结果:

# A tibble: 2 x 2
  gene  plot    
* <fct> <list>  
1 alpha <S3: gg>
2 beta  <S3: gg>

这不是:

plots <- df %>% 
    group_by(gene) %>%
    do({
        plot <- ggplot(.,aes(position,score)) +
            geom_point()

        if (all(.$strand=="-")) {
            plot <- plot + scale_y_reverse()
        }
        data.frame(., plot) ##!! <<< how to get the ggplot object into a data frame
    })
plots

失败,并显示错误:

Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
  cannot coerce class "c("gg", "ggplot")" to a data.frame

2 个答案:

答案 0 :(得分:3)

我认为您不需要将返回值作为框架。试试这个:

O(n log n)

我认为一个问题是您的条件逻辑很好,但是您没有在plots <- df %>% group_by(gene) %>% do(plot= { p <- ggplot(.,aes(position,score)) + geom_point() if (all(.$strand == "-")) p <- p + scale_y_reverse() p }) plots # Source: local data frame [2 x 2] # Groups: <by row> # # A tibble: 2 x 2 # gene plot # * <fct> <list> # 1 alpha <S3: gg> # 2 beta <S3: gg> 中命名该块。

您可以通过以下方式查看其中之一:

do(...)

sample plot

如果您要转储所有图解(例如在降价文档中),只需执行plots$plot[[1]] ,它们就会很快循环通过(在控制台上没有用)。

答案 1 :(得分:1)

我们可以使用嵌套数据框代替do

library(ggplot2)
library(tidyverse)

plots <- df %>%
  group_by(gene) %>%
  nest() %>%
  mutate(plots = data %>% map(~{
    plot <- ggplot(.,aes(position,score)) +
      geom_point()

    if (all(.$strand=="-")) {
      plot <- plot + scale_y_reverse()
    }
    return(plot)
  })) %>%
  select(-data) 

输出:

# A tibble: 2 x 2
  gene  plots   
  <fct> <list>  
1 alpha <S3: gg>
2 beta  <S3: gg>

enter image description here enter image description here