-3
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?

Uwe
  • 41,420
  • 11
  • 90
  • 134
zhi li
  • 1
  • 2
  • 1
    Welcome to SO! Zhi li, this makes very little sense without some context, please realize that nobody else knows what you do about `icadata`. Please make this question *reproducible*. This includes sample code (including listing non-base R packages), sample *unambiguous* data (e.g., `dput(head(x))` or `data.frame(x=...,y=...)`), and expected output. Refs: https://stackoverflow.com/questions/5963269, https://stackoverflow.com/help/mcve, and https://stackoverflow.com/tags/r/info. – r2evans Dec 23 '19 at 04:25
  • 1
    Every time `ggplot` is called, it overwrites the previous plots and draw new plots on a fresh canvas, then displays that last plot drawn. This is why you get only the last plot every time you run the code, because the loop makes a new plot every iteration. What are you trying to achieve? – Nuclear03020704 Dec 23 '19 at 04:30
  • I want to get all the histgrams of numerical variables in my icadata.It's inconvenientto plot one-by-one,so I try to use this for-loop to plot them and save them in a list.Do you know how to correct it?Thanks. – zhi li Dec 23 '19 at 04:58
  • You want to get all the histograms into one plot? That would be unreadable. Using facets instead would be more helpful. – Phil Dec 23 '19 at 05:17
  • Not in one plot,I want to use a list to save them. – zhi li Dec 23 '19 at 05:39

3 Answers3

1

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)])
StupidWolf
  • 45,075
  • 17
  • 40
  • 72
0
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.

zhi li
  • 1
  • 2
0

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, e.g.,

p[[3]]

enter image description here

Please, note that the x-axis is labeled by the column name, e.g., 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"
Uwe
  • 41,420
  • 11
  • 90
  • 134