【问题标题】:Saving ggplot2 output in R to pdf file when using dplyr and mapply function使用 dplyr 和 mapply 函数时将 R 中的 ggplot2 输出保存到 pdf 文件
【发布时间】:2017-01-11 01:48:19
【问题描述】:

我仍在学习 R(很明显),并且在尝试将 ggplot2 输出保存到 pdf 文件时无法弄清楚我的问题可能出在哪里。我已经能够使用循环创建代码来保存 ggplot 输出,但我想强迫自己避免循环并利用 R 这样做的能力。

我查看了有关保存 pdf 文件的其他帖子,但似乎没有一个解决我的问题。

这是一个可重现的例子:

# Create example data frame for reproducible example
amount <- c(rep(5, 25), rep(10, 50), rep(15, 25))
value  <- c(rep(100, 20), rep(200, 30), rep(300, 50))
fund   <- I(c(rep("FundA", 50), rep("FundB", 50)))            

example_df  <- data.frame(amount, value, fund)
#==============================================================
# Weighted histogram function for plotting

histogram_wt_fx <- function(my_df, xvar, my_weight,
                        chart_title  = "title", 
                        chart_xlabel = "x", 
                        chart_ylabel = "y") {
library(ggplot2)

histogram <- ggplot(my_df, aes(x = xvar, weight = my_weight)) + 
geom_histogram(binwidth=0.25, colour="black", fill="white")

# add another layer showing weighted avg amount
histogram <- histogram + geom_vline(aes(xintercept = sum (xvar*my_weight)), 
                                  color="red", linetype="dashed", size=1) +
 labs(title = chart_title , x = chart_xlabel, y = chart_ylabel)
}

#===============================================================
# Function to weight data and plot histogram
# Note: fund_wtd_fx in turn calls histogram_wt_fx

fund_wtd_fx <- function(my_df, my_title) {
  my_df <- my_df %>%
    mutate(pct_amount = amount/sum(amount)) 

  my_df %>%
    histogram_wt_fx (xvar         = my_df$value,
                 my_weight    = my_df$pct_amount,
                 chart_title  = my_title,
                 chart_xlabel = "Amount", 
                 chart_ylabel = "Percent") %>%  
    plot()  #%>%
    #*** This is where the problem code is ****
    #pdf()   %>%
    #plot() 

}
#=====================================
# Extract fund lists from larger data set and run the functions on this list

fund_names <- unique(example_df$fund)     # List of funds in the data frame 
fund_dfs <- list()                        # Initialize list of data frames

# Create list of fund data frames
for (myfund in fund_names) {
  myfund <- example_df %>%
    filter(fund == myfund)
  fund_dfs[[length(fund_dfs)+1]] <- myfund
}
rm(myfund)
names(fund_dfs) <- fund_names

# Assign list of fund names to the list of data frames
for (i in 1:length(fund_names)) {
  assign(fund_names[[i]], fund_dfs[[i]])
}

# Run histogram function on each fund
my_title <- as.list(paste0("Some title for ", (names(fund_dfs))))
mapply(FUN = fund_wtd_fx, fund_dfs, my_title)
#dev.off()

我的问题: 此代码按我希望的方式运行,但如果您取消注释第 39、41、42 和 68 行(假设您从第 1 行开始粘贴代码),则不会保存绘图并且抛出 plot.window 错误。

我原以为未注释的第 39 行上的管道运算符会输入 pdf 函数,以在 mapply 函数循环遍历数据帧时保存绘图输出。最终这就是我想要做的——用这段代码将生成的图保存到一个 pdf 文件中。

非常感谢您的任何帮助或建议。

【问题讨论】:

  • ggsave 很好。
  • 阿利斯泰尔,感谢您的评论。我返回并使用以下行更改了我的代码:ggsave(filename = paste0(my_title,".pdf"), device = "pdf") 我在第 39 行之后添加了这一行(管道运算符仍被注释掉)。为了他人的利益,这也奏效了。

标签: r pdf ggplot2 dplyr


【解决方案1】:

histogram_wt_fx() 现在将绘图对象返回给fund_wtd_fx(),fund_wtd_fx() 现在也返回绘图对象。

从mapply 切换到purrr::map2() 并在最后进行了绘图。

看看,试一试,如果我可以/应该解释更多,请告诉我。

library(dplyr)
library(ggplot2)
library(purrr)

amount <- c(rep(5, 25), rep(10, 50), rep(15, 25))
value  <- c(rep(100, 20), rep(200, 30), rep(300, 50))
fund   <- I(c(rep("FundA", 50), rep("FundB", 50)))            

example_df  <- data.frame(amount, value, fund)

histogram_wt_fx <- function(my_df, xvar, my_weight,
                            chart_title  = "title", 
                            chart_xlabel = "x", 
                            chart_ylabel = "y") {

  histogram <- ggplot(my_df, aes(x = xvar, weight = my_weight)) + 
    geom_histogram(binwidth=0.25, colour="black", fill="white")

  histogram <- histogram + geom_vline(aes(xintercept = sum (xvar*my_weight)), 
                                      color="red", linetype="dashed", size=1) +
    labs(title = chart_title , x = chart_xlabel, y = chart_ylabel)

  histogram

}

fund_wtd_fx <- function(my_df, my_title) {

  my_df <- my_df %>%
    mutate(pct_amount = amount/sum(amount)) 

  my_df %>%
    histogram_wt_fx(xvar         = my_df$value,
                    my_weight    = my_df$pct_amount,
                    chart_title  = my_title,
                    chart_xlabel = "Amount", 
                    chart_ylabel = "Percent")  

}

fund_names <- unique(example_df$fund)     # List of funds in the data frame 
fund_dfs <- list()                        # Initialize list of data frames

for (myfund in fund_names) {
  myfund <- example_df %>%
    filter(fund == myfund)
  fund_dfs[[length(fund_dfs)+1]] <- myfund
}
rm(myfund)
names(fund_dfs) <- fund_names

for (i in 1:length(fund_names)) {
  assign(fund_names[[i]], fund_dfs[[i]])
}

my_title <- as.list(paste0("Some title for ", (names(fund_dfs))))

plots <- map2(fund_dfs, my_title, fund_wtd_fx)

pdf()
walk(plots, print)
dev.off()

【讨论】:

  • 这太好了,如果您不介意,请回答几个问题,所以我理解:1)您知道为什么我以前的代码不起作用吗? 2)如果我想查看 R 中的情节,我会认为我会这样做: plot(plots) 但这似乎不起作用。
  • 主要是 mapply 正在修改返回值。你可以做plot(plots[[1]])和plot(plots[[2]])或do.call(gridExtra::grid.arrange, plots)
  • 啊,当然是在地块列表中选择项目。再次感谢!
猜你喜欢
  • 2013-04-07
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 2018-10-12
  • 2021-11-21
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
相关资源
最近更新 更多