Reputation: 6726
Perhaps the problem has been asked and solved, but the solution didn't work for me.
I wrote a function able to create ggplot objects and return them in a vector. The following is the code inside the function, vars
is a vector of column names of my data d
.
plotting <- function(d){
P <- numeric(0)
vars <- names(d)[!names(d)%in%c('channel','label')]
for (var in vars){
p <- ggplot(d, aes(x=channel,y=var)) +
geom_boxplot(aes(fill=label)) + ggtitle(var)
P <- c(P,p)
}
return(list(plots=P, num=length(vars)))
}
What I want to do is to use the above function to return a concatenated lists P
consisting of several ggplots objects as following which is the 'manual' version working fine:
p1 <- ggplot()+ ...
p2 <- ggplot()+ ...
p3 <- ggplot()+ ...
pdf('...')
grid.arrange(p1, p2, p3, nrow = 3)
dev.off()
The purpose of returning num
is for latter usage in layout arg. of grid.arrange
function. I have PLOTS
as returning variable:
PLOTS <- plotting(d)
pdf('...')
grid.arrange(PLOTS$plots, PLOTS$num)
dev.off()
and I got error:
Error in arrangeGrob(..., as.table = as.table, clip = clip, main = main, :
input must be grobs!
So I tried the solution in Passing a vector to grid.arrange as a list of arguments.
do.call(grid.arrange, c(PLOTS$plots, nrow = PLOTS$num))
but still get the same error. Any comment would be appreciated.
Edit: made problem description clearer, and paste the reproducible data d
below:
structure(list(percent = c(0.0962463533974437, 0.129409967469436,
0.0150265653130588, 0.00299276735619027, 0.0108596845008112,
0.00407417010800106), songs = c(0.231617443342384, 0.430320945945946,
0.109264389042782, 0.282109656611649, 0.0288753799392097, 0.041635687732342
), label = c("1", "1", "1", "1", "1", "1"), channel = c("2",
"2", "2", "2", "2", "2")), .Names = c("percent", "songs", "label",
"channel"), row.names = c(NA, 6L), class = "data.frame")
Please input d
as argument to plotting
and proceed to PLOTS$plots
to help me for debugging, thank you!
Upvotes: 6
Views: 6522
Reputation: 22333
Your plotting function has a few problems. First you need to initialize P
as a list
. Second, you need to use aes_string
instead of aes
, if you want to use the character
input var
. And then you have to use list(p)
, to keep the ggplot
object intact.
plotting <- function(d){
P <- list()
vars <- names(d)[!names(d)%in%c('channel','label')]
for (var in vars){
p <- ggplot(d, aes_string(x='channel', y=var)) +
geom_boxplot(aes(fill=label)) + ggtitle(var)
P <- c(P, list(p))
}
return(list(plots=P, num=length(vars)))
}
PLOTS <- plotting(d)
do.call(grid.arrange, c(PLOTS$plots, nrow = PLOTS$num))
Upvotes: 7