user1471980
user1471980

Reputation: 10646

class try returning error in ggplot

I like to run method="loess" on my data set and if errors, I like to try the lm method. Below is my code to do this, but it is still failing, any ideas?

df

Date  Duration  Athlete
1/1/2012  60    A
1/2/2012  30    A
1/3/2012  10    B
1/1/2012  5     C
1/2/2012  5     C
1/4/2012  4     C

ggplot(df, aes(Date, Duration, group=Athlete)) + geom_point(position="jitter", size=0.5) +theme_solarized(light = FALSE) +  geom_smooth(method=ifelse(class(try(loess(Duration~Date, df)))=="try-error", "lm","loess"), se=T)

I get this error:

Error in simpleLoess(y, x, w, span, degree, parametric, drop.square, normalize,  :
  NA/NaN/Inf in foreign function call (arg 2)
In addition: Warning message:
In simpleLoess(y, x, w, span, degree, parametric, drop.square, normalize,  :
  NAs introduced by coercion
Error in function (el, elname)  :

Upvotes: 2

Views: 582

Answers (2)

agstudy
agstudy

Reputation: 121608

I think it is better to know which smoothing method you pass to the ggplot2 stat engine.

For example:

mym <- "loess"
tryCatch(loess(Duration~Date, dat), 
         error = function(e) mym <<- "lm")

Then

ggplot(dat, aes(Date, Duration, group=Athlete)) + 
  geom_point(position="jitter", size=0.5) + 
  geom_smooth(method=mym, se=T)

Upvotes: 4

joran
joran

Reputation: 173677

You really shouldn't be trying to do this within ggplot2. geom_smooth is not intended to be a replacement for actual model fitting tools. It is an exploratory tool for quick and dirty visualizations.

Instead, fit the models outside of ggplot and then add the fitted values to the data frame, which you can then pass to ggplot.

Your example data is too small to really produce sensible fitted values, so here's a sketch of how you might go about this:

library(plyr)
dat <- read.table(text = "Date  Duration  Athlete
1/1/2012  60    A
1/2/2012  30    A
1/3/2012  10    B
1/1/2012  6     C
1/2/2012  5     C
1/4/2012  4     C
1/5/2012  3     C
1/6/2012  2.5   C",header = TRUE,sep = "")

dat$Date <- as.Date(dat$Date)
dat$Date1 <- as.integer(dat$Date)
foo <- function(x){
    m <- try(loess(Duration~Date1,data = x),silent = TRUE)
    if (inherits(m,"try-error")){
        m <- lm(Duration~Date,data = x)
    }
    return(m)
}

dlply(dat,.(Athlete),foo)

Instead of dlply you'll likely want to use ddply, and instead of simply returning the fitted model, you'll want to add a column to x with the fitted values and then return the modified x.

You will likely still get warning messages printed out from loess when that method doesn't work.

Upvotes: 3

Related Questions