使用dplyr和mapply函数时,将Rg中的ggplot2输出保存为pdf文件

时间:2016-09-02 21:30:40

标签: r pdf ggplot2 dplyr

我还在学习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文件中。

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

1 个答案:

答案 0 :(得分:1)

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

purrr::map2()切换到mapply,然后在最后进行绘图。

看看,试一试,让我知道我是否可以/应该解释一下。

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