1
df <- data.frame(Tag = c(1, 1, 1, 1, 2, 2, 2, 2),
             x = c(9,7,3,2,1,1,1,1),
             y = c(1,2,3,4,1,2,3,4))

cor_fun<- function(x,y){
           val <- cor(x,y)
           return(val)}

df %>%
group_by(Tag) %>%
  summarise(c = cor_fun(x,y))

Here we are trying to compute correlation between x & y by group_by(Tag).the problem is when we compute correlation for x & y and , any one of the columns has standard deviation 0 it spits error of the standard deviation is zero which is not acceptable in production. so what I except is whenever the standard deviation is zero occurs the function should return mean of x else correlation output should be returned.i have tried reproducing the same scenario which is pasted below please guide me on this. using try-catch in Function name cor_fun.

Brief Requirement

  1. Inside Function, we can use try-catch function and look for the standard deviation is zero this error,
  2. If the standard deviation is zero this error occurs Function shall return mean of x.
  3. If an error is not found then return cor(x,y) output.

Here the screen shot of error message

Expected is no error message instead function should return mean of x value.

Harvey
  • 245
  • 2
  • 9

1 Answers1

4

You could just precalculate standard deviation and if it fails the check, return mean of x.

cor_fun<- function(x,y){

  if (any(sapply(list(x, y), FUN = sd) == 0)) {
    return(mean(x))
  } else {
    val <- cor(x,y)
    return(val)
  }
}

df %>%
  group_by(Tag) %>%
  summarise(c = cor_fun(x,y))

# A tibble: 2 x 2
    Tag      c
  <dbl>  <dbl>
1     1 -0.977
2     2  1 

If you want to go the tryCatch route, you could do

cor_fun<- function(x,y){
  val <- tryCatch(cor(x, y), error = function(e) e, warning = function(w) w)
  if (any(class(val) %in% c("simpleWarning", "warning"))) {
    return(mean(x))
  } else {
    return(val)
  }
}

tryCatch evaluates an expression, in your case cor(x, y). If the expression returns an error or warning, it will store that error in val and move on to the next line. If the expression evaluates as expected, it will be stored in val like nothing happened. When an error or warning occur, the class of val changes from expected e.g. numeric to simpleWarning or simpleError. I use that to catch if evaluation of the expression failed and handle it. This handling could also be done inside the function(e) e call.

Here's handling the warning witnin the tryCatch call.

cor_fun<- function(x,y){
  val <- tryCatch(cor(x, y), 
                  error = function(e) e,
                  warning = function(w) {
                    # in case there is a warning (for whatever reason)
                    # return mean of x
                    return(mean(x))
                  })
  val
}

You can read more in the ?tryCatch documentation or e.g. here.

Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
  • .! Thank you for replying. can you please explain tryCatch code: – Harvey Aug 04 '18 at 05:55
  • @Harvey sure, see my comment. Note that documentation for `tryCatch` is not the worst. There are also other online resources you could go through to understand this bit. – Roman Luštrik Aug 04 '18 at 07:55