Home > front end >  Break out of a function quietly and no-debug using if statement (or anything else)
Break out of a function quietly and no-debug using if statement (or anything else)

Time:09-17

Is it possible to break out of a function quietly and no-debug using if statement (or anything else)?

Purpose: I would like to escape from a function (like the break statement in for loop) if specific conditions were met. The function is expected to be utilized in the similar way as mean() (for example) and sometimes within dplyr manipulation and for loop. Besides, I wish to avoid complex nested if-else statement.
v <- c(1, 2, 5, 1, 2)

break5 <- function(x){
    # If this exception occur, then
    # end up (escape ?) the whole function
    if (x == 5){
        # next      # <-- This will raise error message
        break     # <-- This will raise error message
        # stop()  # <-- This will raise debugging event
    } 
    
    # Otherwise, proceed the subsequent process
    if (x == 1) print(1)
    if (x == 2) print(2)
}

Console Output:

> break5(1)
[1] 1

> break5(2)
[1] 2

> break5(5)
Error in break5(5) : no loop for break/next, jumping to top level

Expect to get silent result as the break in for loop

for (i in v){
    if (i == 5) break # <-- Similar with this procedure that 
                      #     could be included in the function
    break5(i)
}

Example 1

x0 <- 1:100
y0 <- 1:100

example <- function(x = NULL, y = NULL){
  
  if (is.null(x) | is.null(y)){    
    break                            # Case 1
  }
  
  if (!(x %in% x0) | !(y %in% y0)){
    break                            # Case 2
  }
  
  if (x < 2){
    z <- 1                           # Case 3
    return(z)
  }
  
  if ((x >= 80) & (x <= 100)){
    break                            # Case 4
  }
  
  z <- x   y                        # Otherwise
  return(z)
}

example(1)    # Case 1, this should be muted
example(30, 999)    # Case 2, this should be muted
example(1, 1)    # Case 3, this is OK
example(80, 1)    # Case 4, this should be muted
example(11, 1)    # Otherwise, this is OK

Example 2:

for (i in 75:90){
  print(paste0(i, ' ', i, '=', example(i, i)))  # The rest should be muted
}

CodePudding user response:

Yes, it's possible to do so by returning a suppressWarnings() expr.

x0 <- 1:100
y0 <- 1:100

example <- function(x = NULL, y = NULL){
    
    if (is.null(x) | is.null(y)){
        return(suppressWarnings(warning()))     # Case 1
    }
    warning
    if (!(x %in% x0) | !(y %in% y0)){
        return(suppressWarnings(warning()))     # Case 2
    }
    
    if (x < 2){
        z <- 1                                  # Case 3
        return(z)
    }
    
    if ((x >= 80) & (x <= 100)){
        return(suppressWarnings(warning()))     # Case 4
    }
    
    z <- x   y                                  # Otherwise
    return(z)
}

Example 1

example(1)          # Case 1, Error/Warning message was muted
example(30, 999)    # Case 2, Error/Warning message was muted
example(1, 1)       # Case 3, this is OK
example(80, 1)      # Case 4, Error/Warning message was muted
example(11, 1)      # Otherwise, this is OK

Console output:

> example(1)
> example(30, 999) 
> example(1, 1) 
[1] 1
> example(80, 1)
> example(11, 1)
[1] 12

Example 2

for (i in 75:90){
    print(paste0(i, ' ', i, '=', example(i, i)))  # The rest was muted
}

Console output:

> for (i in 75:90){
      print(paste0(i, ' ', i, '=', example(i, i)))
  }
[1] "75 75=150"
[1] "76 76=152"
[1] "77 77=154"
[1] "78 78=156"
[1] "79 79=158"
[1] "80 80="
[1] "81 81="
[1] "82 82="
[1] "83 83="
[1] "84 84="
[1] "85 85="
[1] "86 86="
[1] "87 87="
[1] "88 88="
[1] "89 89="
[1] "90 90="
  • Related