codingknob
codingknob

Reputation: 11660

any cleaner/elegant way to create lists of lists without using 'for' construct?

I have a need to create an object to calculate and store 3 sets of power prices (on-peak, off-peak, and a day average) for 14 nodes in a grid for each month of the year for the past two years. I thought that an embedded list data structure would be appropriate (correct me if this isn't optimal).

In any case I'm not a fan of using for loops to create this structure. If there is an elegant way to do this I would be grateful if someone could help steer me in the right direction. I'm trying to practice and improve my coding. Thank you.

hb_lz_names <- c("HB_BUSAVG", "HB_HOUSTON", "HB_HUBAVG", "HB_NORTH", "HB_SOUTH", 
"HB_WEST", "LZ_AEN", "LZ_CPS", "LZ_HOUSTON", "LZ_LCRA", "LZ_NORTH", 
"LZ_RAYBN", "LZ_SOUTH", "LZ_WEST")

power_price <- list()
for (i in 1:2){
  power_price[[i]] <- list()
  for (j in 1:12){
    power_price[[i]][[j]] <- list()
    for (k in 1:NROW(hb_lz_names)) {
      power_price[[i]][[j]][[k]] <- list()
      for (l in 1:3){
        power_price[[i]][[j]][[k]][[l]] <- l
      }
      names(power_price[[i]][[j]][[k]]) <- c("on-peak", "off-peak", "average")
    }
    names(power_price[[i]][[j]]) <- hb_lz_names
  }
  names(power_price[[i]]) <- c("jan", "feb", "mar", "apr", "may", "jun", "jul", "aug",
                             "sep", "oct", "nov", "dec")
}
names(power_price) <- c("2011", "2012")

Upvotes: 4

Views: 130

Answers (1)

Ben Bolker
Ben Bolker

Reputation: 226067

I think that for a regular (not ragged) data set like this you will be much better off using an array:

period_names <- c("on-peak", "off-peak", "average")
hb_lz_names <- c("HB_BUSAVG", "HB_HOUSTON", "HB_HUBAVG", "HB_NORTH", "HB_SOUTH", 
"HB_WEST", "LZ_AEN", "LZ_CPS", "LZ_HOUSTON", "LZ_LCRA", "LZ_NORTH", 
"LZ_RAYBN", "LZ_SOUTH", "LZ_WEST")
yrs <- 2011:2012

power.price <- array(1,dim=c(2,12,length(hb_lz_names),length(period_names)))
dimnames(power.price) <- list(year=yrs,month=month.abb,node=hb_lz_names,
                              period=period_names)

(Giving names to the elements in the dimnames list -- i.e. naming your dimensions -- can be a big help in trying to remember the array structure ...)

You can then easily compute averages (or other summary statistics) across the appropriate margins by using apply, and convert to long format (for ggplot graphics or statistical analysis) using reshape2::melt ... in my experience, deeply nested lists are a pain in the butt.

Upvotes: 5

Related Questions