我仍在学习 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 文件中。
非常感谢任何帮助或建议。
最佳答案
histogram_wt_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()
关于r - 使用 dplyr 和 mapply 函数时将 R 中的 ggplot2 输出保存到 pdf 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39300959/