giraffehere giraffehere - 1 year ago 49
R Question

Regular Expression Select Comma But Not In Between Parentheses

I'm looking to create a function in R that loads the defaults of a given function. To do this, I'm using the

argument on a function and looking to break it down to the defaulted arguments of the function and load those into the global environment. This takes a bit of regular expressions and have bumped into this that I'm having difficulty addressing.

Here is a sample function:

myFunc <- function(a = 1, b = "hello world", c = c("Hello", "World")) {}

I've gotten it down to this point using my own functions:

x <- "a = 1, b = \"hello world\", c = c(\"Hello\", \"World\")"

However, where I am struggling is on splitting the function arguments up. I wanted to split on a comma, but if you have a function argument that has a comma within the default (like the
argument does), then that causes issues. What I'm thinking is if there is a way to call a regular expression that matches a comma, but not a comma this in between two parentheses, then I could use
with that expression to get what I want.

My attempt to match the case of a comma between two parentheses looks like this:


Now, I've looked into how to do what I described above and it seems like a negative look ahead may be what I need, so I've attempted to do something like this.

splitx <- strsplit(x, "(?!\\(.*,.*\\)(,)")

But R tells me it is an illegal regular expression. If I set
perl = TRUE
in the argument, it just returns the same string. Any help here would be greatly appreciated and I hope I've been clear!

Answer Source

I'm going to try and answer your underlying question.

The function formals() returns a pairlist of the formal arguments of a function. You can use the result of formals() by testing for is.symbol() and is.null(). Anything that isn't a symbol and isn't null either, contains a default value.

For example:

get_default_args <- function(fun){
  x <- formals(fun)
  w <- sapply(x, function(x)!is.symbol(x) && !is.null(x))

Try it on lm():

[1] "qr"

[1] TRUE



[1] TRUE

[1] TRUE

Try it on your function:

myFunc <- function(a = 1, b = "hello world", c = c("Hello", "World")) {}
[1] 1

[1] "hello world"

c("Hello", "World")

Note that the comments suggests using This may or may not work for you, but evaluates the argument in the environment of the function after being called, whereas formals() evaluates the language object itself. Therefore you don't need to call the function at all when using formals().