简体   繁体   中英

Using for loop to create multiple ggplots

p[[2]]<-ggplot(data = icadata, aes(x = icadata[[2]])) + geom_histogram()    
p[[3]]<-ggplot(data = icadata, aes(x = icadata[[3]])) + geom_histogram()    
p[[4]]<-ggplot(data = icadata, aes(x = icadata[[4]])) + geom_histogram()    
p[[5]]<-ggplot(data = icadata, aes(x = icadata[[5]])) + geom_histogram()    
p[[6]]<-ggplot(data = icadata, aes(x = icadata[[6]])) + geom_histogram()    
p[[7]]<-ggplot(data = icadata, aes(x = icadata[[7]])) + geom_histogram()    
p[[8]]<-ggplot(data = icadata, aes(x = icadata[[8]])) + geom_histogram()    
p[[9]]<-ggplot(data = icadata, aes(x = icadata[[9]])) + geom_histogram()    
p[[10]]<-ggplot(data = icadata, aes(x = icadata[[10]])) + geom_histogram()    
p[[11]]<-ggplot(data = icadata, aes(x = icadata[[11]])) + geom_histogram()    
p[[12]]<-ggplot(data = icadata, aes(x = icadata[[12]])) + geom_histogram()    
p[[13]]<-ggplot(data = icadata, aes(x = icadata[[13]])) + geom_histogram()    
p[[16]]<-ggplot(data = icadata, aes(x = icadata[[16]])) + geom_histogram()    

p <- list()    
for(i in c(2:13,16) ) {      
           p[[i]]<-ggplot(data = icadata, aes(x = icadata[[i]])) + geom_histogram()    
}     

What's the difference between the codes above?
Why do I get always the same picture after runnning the for loop code?

if you look at the plot you get, it is the last plot that appears. ggplot2 only evaluates the function when you call it. And by entering the x value as icadata[[i]], ggplot2 only plots the icadata[[16]].

So if you do need to use the for loop, it is much better to point it directly to the column inside icadata:

icadata = data.frame(sapply(1:16,function(i)rnorm(100,i,1)))

for(i in c(2:13,16) ) {
COLUMN=colnames(icadata)[i]
p[[i]]<-ggplot(data = icadata, aes_(x = as.name(COLUMN))) + geom_histogram()  
# or use 
# p[[i]]<-ggplot(data = icadata, aes_string(x = COLUMN)) + geom_histogram()    
}  

grid.arrange(grobs=p[c(2:13,16)])
library(reshape2)
d <- melt(icadata[,-c(1,14,15)])
ggplot(d,aes(x = value)) + 
  facet_wrap(~variable,scales = "free_x") + 
  geom_histogram()

I tried facets instead.It worked.But I am still confused why I can't get a plot list using that for-loop code unless I plot them one-by-one like the very beginning of my code.

I have been able to reproduce the observed behaviour using the mtcars dataset. To me, it seems that the way how aes(x = icadata[[2]]) is specified might be the issue.

The code below does work for me:

icadata <- as.data.frame(mtcars) # create reproducible data
library(ggplot2)

p <- list()    
for(i in c(2:3, 6)) {
  p[[i]] <- ggplot(data = icadata, aes(x = !!sym(names(icadata)[i]))) + geom_histogram()    
}    

Output is a list as requested by the OP

class(p)
 [1] "list"

with the list elements either empty or a ggplot object

lapply(p, class)
 [[1]] [1] "NULL" [[2]] [1] "gg" "ggplot" [[3]] [1] "gg" "ggplot" [[4]] [1] "NULL" [[5]] [1] "NULL" [[6]] [1] "gg" "ggplot"

I am able to plot the whole list by

lapply(p, print)

or a single graph with, eg,

p[[3]]

在此处输入图片说明

Please, note that the x-axis is labeled by the column name, eg, disp instead of icadata[[3]] .


If desired, the for loop can be replaced by a call to lapply() which returns a list object without empty elements. In addition, the list elements can be named appropriately.

cols <- names(icadata)[c(2:3, 6)]
p2 <- lapply(
  cols, 
  function(col) ggplot(data = icadata, aes(x = !!sym(col))) + geom_histogram()
  )
names(p2) <- paste0(cols, "_histogram")

lapply(p2, class)
 $cyl_histogram [1] "gg" "ggplot" $disp_histogram [1] "gg" "ggplot" $wt_histogram [1] "gg" "ggplot"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM