davidcarslaw / openair

Tools for air quality data analysis
https://davidcarslaw.github.io/openair/
GNU General Public License v2.0
303 stars 113 forks source link

Plotting Wind Roses within Loop #31

Closed JaysonAP closed 8 years ago

JaysonAP commented 8 years ago

I want to generate a number of wind roses within a loop, rather than reiterating over each individual station identifier. I have meteorological data frames named by each ICAO identifier within the global environment, and have a data frame 'Stations' that has a list of each ICAO identifier that is used to loop through and call each individual sites data.

head(Stations)
Name ICAO  WBAN   USAF
Chanute Martin Johnson Airport KCNU 13981 724507
Coffeyville Municipal Airport KCFV 93967 724519
Dodge City Regional Airport KDDC 13985 724510

Here's my loop that I am attempting to run.

require(openair)

for (site in Stations$ICAO) {
  imagedir = "~/R/MetData/WindRoses/2010-2014/Overall/"
  png(filename=paste0(imagedir,site,".png"),width=8*300,height=8*300,res=300)
  windRose(site,type="default",breaks=c(0,1,2,5,10),auto.text= FALSE, paddle = FALSE, 
           annotate = FALSE, cols=c("blue","green","yellow","orange","red"),
           key = list(labels = c("0-1","1-2","2-5","5-10",">10")),
           key.footer="m/s",main=paste0("Cumulative Wind Rose\n",site," Hourly Observations (2010-2014)"))
  dev.off()
}

Running this loop provides me with an error Error in mydata[[wd]] : subscript out of bounds

The data is formatted properly, as if I run the loop but include the site directly within the code it produces the wind rose. Is this something within OpenAir that won't allow me to use a variable within the WindRose function? I've used similar loops on other data within functions that works properly.

Thanks

davidcarslaw commented 8 years ago

I think your site in the loop is just a string rather than a data frame. Do you have individual data frames such as KCNU or are all the met data in a single data frame? I quite like using the plyr package for this sort of thing - it can simplify the code. If you can send me the data I can take a look...(david.carslaw@york.ac.uk)

JaysonAP commented 8 years ago

I have individual data frames for the met data.

I will send you over example data shortly. Thanks

davidcarslaw commented 8 years ago

OK, it is because your site is actually a string and not the data object. You will need to do something like (note the get):

for (site in Stations$ICAO) {
  imagedir = "~/R/MetData/WindRoses/2010-2014/Overall/"
  png(filename=paste0(imagedir,site,".png"),width=8*300,height=8*300,res=300)
  windRose(get(site), breaks=c(0,1,2,5,10), auto.text= FALSE, paddle = FALSE, 
           annotate = FALSE, cols=c("blue","green","yellow","orange","red"),
           key = list(labels = c("0-1","1-2","2-5","5-10",">10")),
           key.footer="m/s",main=paste0("Cumulative Wind Rose\n",site," Hourly Observations (2010-2014)"))
  dev.off()
}

You might also want to catch missing data if that is a problem. You could use another line to trap that e.g.

if(!exists(site)) return()

that will avoid tripping up on any missing data frames should they be in your list.

JaysonAP commented 8 years ago

Thanks!

Yes, using get() properly grabs the data frame.

Thanks for the tip on using !exists as well.