我想使用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
答案 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(...)
如果您要转储所有图解(例如在降价文档中),只需执行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>