代码之家  ›  专栏  ›  技术社区  ›  Richard J. Acton

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

  •  2
  • Richard J. Acton  · 技术社区  · 6 年前

    我想用 do

    我模仿了哈德利对这个问题的回答: dplyr::do() requires named function?

    我遇到的问题是将gg对象放入数据帧以返回它,如何手动执行 在我下面的工作示例中,是否自动将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 回复  |  直到 6 年前
        1
  •  3
  •   Community Dunja Lalic    4 年前

    我不认为你需要返回值是一个框架。试试这个:

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

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

    plots$plot[[1]]
    

    sample plot

    plots$plot 而且它们会很快循环通过(在控制台上没有那么有用)。

        2
  •  1
  •   acylam    6 年前

    我们可以使用嵌套的数据帧而不是 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