提供函数调用的match.call

时间:2018-12-01 20:34:12

标签: r

我想捕获所有参数和值并返回一个命名列表。我遇到的情况是提供的值是函数调用。

以下内容产生了一个“ call”类的对象,这对我来说不方便,因为我想在其上调用paste

fun1 = function(a = 1) as.list(match.call()[-1])
value1 = fun1(a = letters[1:2])
class(value1[[1]])
[1] "call"
paste(value1[[1]], collapse = " - ")
[1] "[ - letters - 1:2" #not useful to me

作为一种解决方法,我可以调用eval来获取c创建的字符向量(lapply函数用于说明当有多个参数时,将eval调用全部):

fun2 = function(a = 1) lapply(as.list(match.call()[-1]), eval)
value2 = fun2(a = letters[1:2])
class(value2[[1]])
[1] "character"
paste(value2[[1]], collapse = " - ")
[1] "a - b" #that's what I want

有更好的方法吗?在很多事情上调用eval只是为了获取值对我来说有点奇怪。

编辑:其背后的想法是,我想将参数列表传递给原始函数内的函数(该函数接受其中一个参数的命名列表)。我想捕获用户提供的值和默认值(用于用户未提供任何内容的参数)。

我在其他地方学到,可以结合使用match.callformals来获得所有这些。但是,然后说我需要将其传递给query函数的httr::GET参数,并在此之前对其进行一些处理(例如,在“ a”和“ b”之间添加“-” ”)。然后,我得到类似“ [-字母-1:2”而不是“ a-b”的字样。

我感觉到,如果答案使用的是eval,那么我可能会问错问题。

2 个答案:

答案 0 :(得分:1)

我感觉到您正在寻找更一般的东西,因此不确定这是否完全是您要寻找的东西,但它更简单并且可以为您提供所需的结果。关键是do.call()

fun1 = function(a = 1) {
  L1 <- as.list(match.call())
  do.call(paste0, list(L1$a, sep="", collapse=" - "))
}

value1 = fun1(a = letters[1:2])

答案 1 :(得分:1)

嗯,我认为您需要确定代码的哪些部分需要评估,哪些不需要。
从您的示例中还不能完全清楚您想要的通用性,但是您可以通过一个简单的list()解决您的示例问题,您只需要一个自定义函数即可提供默认值:

myfun <- function(a=1) list(a=a)
value <- myfun(a=letters[1:2]))
paste(value[[1]], collapse = " - ")
# Basically: value <- list(a=letters[1:2])), or paste(letters[1:2], collapse= " - ")

通常,您使用不带任何参数的match.call()来找出调用函数的方式。有时了解是否调用过fun(a = c('a','b'))或fun1(a =字母[1:2])很有用,所以match.call会告诉您这一点,而无需评估任何内容。 / p>

因此,如果您想对参数进行实际操作,只需直接调用它们,以后就可以将其传递给另一个函数

mypaste <- function(..., sep=' -CustomSep- ', collapse=' -Mycollapse- ', prefix='Value:') {
  if(length(list(...))>0) {
    paste(prefix, ..., sep=sep, collapse=collapse)
  } else {
    text <- character(0)
  }
}

此功能只是粘贴的一种变体,但您可以根据需要对其进行扩展。

给我的印象是,您需要一个一般情况,即您将参数与另一个函数的参数进行匹配,但是要回答该问题,我需要更多地了解您到底想完成什么。