简体   繁体   English

解析 match.call 到命名列表

[英]deparsed match.call to a named list

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.我在我的一个函数中对调用进行了解析(以使其更具可读性),并将其作为输出 S3 对象的一部分包含在内,以供最终用户参考。

func1 <- function(v1, v2, ...){
    return(deparse(match.call()))
}

obj <- func1(11, 22, v3 = 33)

The obj variable now contains: obj变量现在包含:

"func1(v1 = 11, v2 = 22, v3 = 33)" "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 $v1

[1] 11 [1] 11

$v2 $v2

[1] 22 [1] 22

$v3 $v3

[1] 33 [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).需要明确的是,我不愿意按原样存储调用对象,因为当他们探索 S3 对象时,它不会像用户应该的那样提供信息(我认为程序员应该处理所有事情,而用户应该只是享受功能)。

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.基本上我们将字符串解析回一个表达式,然后用list()函数交换原始函数名称,可以对其进行评估以实际构建列表。

You can do the following considering that the obj is a string as you showed in the question:考虑到obj是您在问题中显示的字符串,您可以执行以下操作:

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:但是如果你想在函数内部使用它,你可以执行以下操作并避免 deparsing 和 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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM