(ROSE plot error) Error: Faceting variables must have at least one value

Lyndz picture Lyndz · Mar 6, 2018 · Viewed 14.5k times · Source

I am trying to plot monthly roseplots in R using the code below but I am encountering an error: "Error: Faceting variables must have at least one value"

Here is the data that I am using Link to data

This code came from a previous post: Rose plot using ggplot

require(ggplot2)
require(RColorBrewer)
require(scales)

plot.windrose <- function(data,
                      spd,
                      dir,
                      spdres = 2,
                      dirres = 22.5,
                      spdmin = 2,
                      spdmax = 20,
                      spdseq = NULL,
                      palette = "YlGnBu",
                      countmax = NA,
                      debug = 0){


  # Look to see what data was passed in to the function
  if (is.numeric(spd) & is.numeric(dir)){
  # assume that we've been given vectors of the speed and direction vectors
   data <- data.frame(spd = spd,
                   dir = dir)
   spd = "spd"
   dir = "dir"
  } else if (exists("data")){
  # Assume that we've been given a data frame, and the name of the speed 
  # and direction columns. This is the format we want for later use.    
  }  

  # Tidy up input data ----
  n.in <- NROW(data)
  dnu <- (is.na(data[[spd]]) | is.na(data[[dir]]))
  data[[spd]][dnu] <- NA
  data[[dir]][dnu] <- NA

# figure out the wind speed bins ----
if (missing(spdseq)){
  spdseq <- seq(spdmin,spdmax,spdres)
} else {
  if (debug >0){
     cat("Using custom speed bins \n")
  }
}
# get some information about the number of bins, etc.
n.spd.seq <- length(spdseq)
n.colors.in.range <- n.spd.seq - 1

# create the color map
spd.colors <- colorRampPalette(brewer.pal(min(max(3,
                                                n.colors.in.range),
                                            min(9,
                                                n.colors.in.range)),                                               
                                        palette))(n.colors.in.range)

 if (max(data[[spd]],na.rm = TRUE) > spdmax){    
 spd.breaks <- c(spdseq,
                max(data[[spd]],na.rm = TRUE))
 spd.labels <- c(paste(c(spdseq[1:n.spd.seq-1]),
                      '-',
                      c(spdseq[2:n.spd.seq])),
                paste(spdmax,
                      "-",
                      max(data[[spd]],na.rm = TRUE)))
 spd.colors <- c(spd.colors, "grey50")
 } else{
 spd.breaks <- spdseq
 spd.labels <- paste(c(spdseq[1:n.spd.seq-1]),
                    '-',
                    c(spdseq[2:n.spd.seq]))    
 }
 data$spd.binned <- cut(x = data[[spd]],
                     breaks = spd.breaks,
                     labels = spd.labels,
                     ordered_result = TRUE)

  # clean up the data
  data. <- na.omit(data)

  # figure out the wind direction bins
  dir.breaks <- c(-dirres/2,
              seq(dirres/2, 360-dirres/2, by = dirres),
              360+dirres/2)  
  dir.labels <- c(paste(360-dirres/2,"-",dirres/2),
              paste(seq(dirres/2, 360-3*dirres/2, by = dirres),
                    "-",
                    seq(3*dirres/2, 360-dirres/2, by = dirres)),
              paste(360-dirres/2,"-",dirres/2))
  # assign each wind direction to a bin
  dir.binned <- cut(data[[dir]],
                breaks = dir.breaks,
                ordered_result = TRUE)
  levels(dir.binned) <- dir.labels
  data$dir.binned <- dir.binned

  # Run debug if required ----
  if (debug>0){    
    cat(dir.breaks,"\n")
    cat(dir.labels,"\n")
    cat(levels(dir.binned),"\n")

  }  

  # create the plot ----
  p.windrose <- ggplot(data = na.omit(data),
                   aes(x = dir.binned,
                       fill = spd.binned
                       ,y = (..count..)/sum(..count..)
                       ))+
    geom_bar() + 
    scale_x_discrete(drop = FALSE,
                 labels = c("N","NNE","NE","ENE", "E", 
                            "ESE", "SE","SSE", 
                            "S","SSW", "SW","WSW", "W", 
                             "WNW","NW","NNW")) +
    coord_polar(start = -((dirres/2)/360) * 2*pi) +
    scale_fill_manual(name = "Wind Speed (m/s)", 
                  values = spd.colors,
                   drop = FALSE) +
    theme(axis.title.x = element_blank(),axis.title=element_text(size=15),
    axis.text=element_text(colour="black",size=12,family="serif"),
    legend.text=element_text(size=12),legend.title=element_text(size=12)) + 
    scale_y_continuous(labels = percent) +
    ylab("Frequency")

   # adjust axes if required
  if (!is.na(countmax)){
    p.windrose <- p.windrose +
  ylim(c(0,countmax))
  }

  # print the plot
  print(p.windrose)  

  # return the handle to the wind rose
  return(p.windrose)
}

##Read Data

dat<-read.csv("test.csv",header=T,sep=",")
dat[dat==-20]<-NA
dat[dat==-2]<-NA
dat[dat==-1]<-0
dat[dat==-10]<-0


dat$Date <- as.POSIXct(paste0(dat$YY,dat$MM,dat$DD),format="%Y,%m,%d")
dat$Year <- as.numeric(format(dat$Date,"%Y"))
dat$month <- factor(format(dat$Date,"%B"),levels=month.name)

#p1 <- plot.windrose(data=dat,spd = dat$WSPD,dir = dat$WDIR,spdseq=c(0,2,4,6,8,10,12,14,16,18,20))

p1 <- plot.windrose(data=dat,spd="WSPD",dir="WDIR")
p2 <- p1 + facet_wrap(~month,ncol=4)
outImg <- paste0("Infanta",".png")

ggsave(outImg,p2)
dev.off()

Questions

[1] Any suggestions on how to do this correctly in R?

Answer

Michael picture Michael · Feb 4, 2020

In case this helps someone else: I came across this error because I had ZERO records in my data frame (due to a pipe & filter) and didn't even realize it.