1

I would like to extract expr_a, expr_b, expr_c from the if/else block in the following function:

test <- function() {

    result <- if (expr_a)
                  expr_b
              else
                  expr_c

    return(result)
}

for the purpose of dead-code elimination (I've seen the rco library but it currently doesn't support all the cases that I'm working with).

I would like to be able to then replace the entire loop with expr_b if eval(expr_a) == TRUE or expr_c otherwise.

The issue with regex-based approaches to this problem is that there are so many possible variations on this, and I'm not sure how to capture them all. For example, the code above is valid R code for one line expressions. Multi-line expressions surrounded by brackets can also be written e.g.:

else
{
    # ...
}

Is there any way to identify and capture every possible if/else statement programmatically in R?


An example of what my real starting point looks like:


test <- function() {
    my_var <- list(my_bool = FALSE)
    my_result <- if(my_var$my_bool) 1
                 else my_var$my_bool + 2
    return(my_result)
}

The ideal output would be: list(expression(my_var$my_bool), expression(1), expression(my_var$my_bool + 2))

adityar
  • 142
  • 5
  • 1
    Yes, using regexp for this is very common nonsense. Perhaps you can use `parse` and maybe there are packages to do this, like [KWB-R](https://rdrr.io/github/KWB-R/kwb.code/man/extract_from_parse_tree.html) (but the docs seems a bit poor). – Tomas Jan 18 '21 at 18:38
  • if the if statement is in a named function, and the environment is known, you could try `as.character(body(mget("test", envir = .GlobalEnv)[["test"]]))`, and then implement a search for regex pattern returning "if ( )". Naturally, replace the name of the function and environment accordingly – Donald Seinen Jan 18 '21 at 18:41
  • 1
    You need to give us a reproducible example. The code you give is *not* legal R code as it stands (it won't parse, even if all the `expr`s are defined). Show us what you are really starting with: a function, a file, some text? It makes a difference. – user2554330 Jan 18 '21 at 19:41
  • I've added an example – adityar Jan 18 '21 at 21:46

1 Answers1

0

Figured it out! as.list can be used to break up calls into the syntax tree.

For example:


example <- quote(
    if (object) {
        print(result_true)
    } else {
        print(result_false)
    }
)

as.list(example)
# [[1]]
# `if`
# 
# [[2]]
# object
# 
# [[3]]
# {
#     print(result_true)
# }
# 
# [[4]]
# {
#     print(result_false)
# }

adityar
  • 142
  • 5