Reputation: 3829
I have a deparsed a call (to make it more human readable) in one of my functions and have included it as part of output S3 object for the reference of the end user.
func1 <- function(v1, v2, ...){
return(deparse(match.call()))
}
obj <- func1(11, 22, v3 = 33)
The obj
variable now contains:
"func1(v1 = 11, v2 = 22, v3 = 33)"
Now in another function that accepts this object as an input, I would like to turn this call character vector into a named list to has the same structure as the following:
list(v1 = 11, v2 = 22, v3 = 33)
$v1
[1] 11
$v2
[1] 22
$v3
[1] 33
To be clear, I'm not willing to store the call object as is since it will not be as informative to user as it should be while they explore the S3 object (I think the programmer should handle everything and the user should just enjoy the function).
Upvotes: 2
Views: 235
Reputation: 47300
You can do the following considering that the obj
is a string as you showed in the question:
eval(parse(text=sub("^.+?\\(","list(",obj)))
But if you would like to have it inside the function, you can do the following and avoid deparsing and parsing:
func1 <- function(v1, v2, ...){
# catch the call
tmp_the_call <- match.call()
# convert to list
tmp_the_call <- as.list(tmp_the_call)
# remove the function name
tmp_the_call <- tmp_the_call[-1]
return(tmp_the_call)
}
# Or as one-liner
func1 <- function(v1, v2, ...){
return(as.list(match.call())[-1])
}
func1("qq", "ww", v3 = "ee", "rr")
which will result in:
$v1 [1] "qq" $v2 [1] "ww" $v3 [1] "ee" [[4]] [1] "rr"
Upvotes: 3
Reputation: 206197
How about this
to_list <- function(x) {
xex <- parse(text= x )[[1]]
xex[[1]] <- quote(list)
eval.parent(xex)
}
to_list(obj)
Basically we parse the string back into an expression, then swap out the original function name with the list()
function can evaluate it to actually build the list.
Upvotes: 4