Another R bleg about loops and graph devices

April 27, 2011 at 4:51 am 7 comments

| Gabriel |

I’m having another problem with R and was hoping somebody could help me out in the comments. Long story short, I can make graphs properly if I do them one at a time, but when I try to loop it I get device errors. In particular it creates the PDFs but they are either empty or corrupted.

Here is the log, which first fails to do it with a loop, then does it right for one case where I manually assign the variables rather than looping.

> # File-Name:       surfacegraphs.R                 
> # Date:            2011-04-25
> # Author:          Gabriel Rossman                                       
> # Purpose:         graph from Stata
> # Packages Used:   lattice   
> # note, wireframe code from lisa 
> timestamp()
##------ Tue Apr 26 10:44:09 2011 ------##
> library(lattice)
> 
> histopath <- '~/Documents/project/histograms'
> image2 <- '~/Documents/project/images/histograms'
> 
> timestamp()
##------ Tue Apr 26 10:44:10 2011 ------##
> 
> #create surface histograms, showing how population evolves over time
> #  parameters held constant
> setwd(histopath)
> for(d in 0:10) {
+ 	for(p in 0:5) {
+ 		d10 <- d*10
+ 		p100 <- p*100
+ 		datafile <- paste(histopath,'/d',d10,'p',p100,'.txt', sep="")
+ 		dataobject <- read.table(file=datafile,header=TRUE)
+ 		pdfcolor <- paste(image2,'/hist_color_d',d10,'p',p100,'.pdf', sep="")
+ 		pdfgrey <- paste(image2,'/hist_grey_d',d10,'p',p100,'.pdf', sep="")
+ 		pdf(pdfcolor)
+ 		wireframe( dataobject$z~dataobject$x*dataobject$y, shade=TRUE) 
+ 		dev.off()
+ 		
+ 		pdf(pdfgrey)
+ 		wireframe( dataobject$z~dataobject$x*dataobject$y, shade=TRUE, par.settings=standard.theme(color=FALSE))
+ 		dev.off()
+ 	}
+ }
There were 50 or more warnings (use warnings() to see the first 50)
> timestamp()
##------ Tue Apr 26 10:44:12 2011 ------##
> 
> #loop doesn't work
> #  seems to be the dev.off()
> #try a few manually
> d10 <- 0
> p100 <- 0
> datafile <- paste(histopath,'/d',d10,'p',p100,'.txt', sep="")
> dataobject <- read.table(file=datafile,header=TRUE)
> pdfcolor <- paste(image2,'/hist_color_d',d10,'p',p100,'.pdf', sep="")
> pdfgrey <- paste(image2,'/hist_grey_d',d10,'p',p100,'.pdf', sep="")
> pdf(pdfcolor)
> wireframe( dataobject$z~dataobject$x*dataobject$y, shade=TRUE) 
> dev.off()
null device 
          1 
> 
> 
> timestamp()
##------ Tue Apr 26 10:44:14 2011 ------##
> 
> 

The warnings start like this and go on from there:

> warnings()
Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
3: In min(x) : no non-missing arguments to min; returning Inf
4: In max(x) : no non-missing arguments to max; returning -Inf
5: In min(x) : no non-missing arguments to min; returning Inf

Any ideas?
Do I just need to hard-code the graphs I really want rather than batching them?

[Update]
As Michal suggested, I needed to wrap wireframe in print. Here’s an example of the output (for a baseline simulation).
hist_color_d0p0

Entry filed under: Uncategorized. Tags: , , .

Simulations, numlist, and order of operations Maybe a reason it would have been better to keep ASA in Chicago

7 Comments

  • 1. michal  |  April 27, 2011 at 7:17 am

    Hard to guess from the code without seeing the data, but I bet that it is the ‘wireframe’ that generates the warnings. Do you have missing data in any of the data files you load for the plotting?

    additional suggestions:

    1. Use ‘file.path’ instead of ‘paste’ for constructing file paths. It is more portable.

    2. Calls to ‘wireframe’ could be simplified, and require less typing/copypaste’ing, using the data argument like this
    wireframe( z ~ x * y, data=dataobject, shade=TRUE)

    HTH

  • 2. Brian Rubineau  |  April 27, 2011 at 8:20 am

    have you tried
    invisible(dev.off())
    ?

  • 3. michal  |  April 27, 2011 at 9:01 am

    another thing which i completely missed:

    plotting in lattice package (based on grid package) is done a bit differently than in base graphics system. when plotting to device like pdf you have to enclose the plotting function call in print function, so

    print( wireframe(z ~ x*y, data=dataobject, shade=TRUE)

  • 4. drschweitzer  |  April 27, 2011 at 11:49 am

    I’m confused by this.

    In min(x) : no non-missing arguments to min; returning Inf
    is lattice telling you that it can’t figure out how to calculate a wireframe because it either is encountering a missing value or some data in a format it doesn’t understand. Taking a look at na.action might help you out here. I thought that lattice could handle missing values, though. dev.off wouldn’t be giving you this message–it would just be failing to close out the pdf and so you’d just wind up with one file, not these warnings.

    If you have trouble with this today email me as I’ll be writing and looking for a reason to procrastinate.

  • 5. gabrielrossman  |  April 27, 2011 at 12:08 pm

    hi everybody,

    thanks to all of you for providing this feedback so quickly.

    michal’s advice at 9:01am turned out to be the answer — i wrapped it in a print function and it worked. not sure why it makes it work (especially when it doesn’t require “print()” when executed outside of a loop). of course i generally don’t grok R so that’s not surprising that i don’t understand this. anyway, it’s working.

    thanks everybody.

    • 6. michal  |  April 27, 2011 at 4:51 pm

      a short answer is that in lattice the plotting functions do not actually create the plot but create an object that contains all the info and data necessary to construct the plot. the actual plotting is done via a print method for these object. when working interactively you do not notice the difference because the print method is invoked automatically to “print” the object to the console. in scripts and devices like pdf you have to call print explicitely

      • 7. gabrielrossman  |  April 27, 2011 at 11:37 pm

        thanks, i never would have guessed that but it makes sense when you explain it


The Culture Geeks


%d bloggers like this: