简体   繁体   English

提供函数调用的match.call

[英]match.call with function call supplied

I'd like to capture all arguments and values and return a named list. 我想捕获所有参数和值并返回一个命名列表。 I'm having trouble with a situation where the value supplied is a function call. 我遇到的情况是提供的值是函数调用。

The following produces an object of class "call", which is inconvenient to me, because I want to call paste on it: 下面产生了一个“ 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

As a workaround, I can call eval to get the character vector created by c (the lapply function is there to illustrate that when having multiple arguments, eval would be called on all of them): 作为一种解决方法,我可以调用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

Is there a better way to do this? 有一个更好的方法吗? Calling eval on a bunch of things just to get the values seems a bit weird to me. 对一堆东西调用eval只是为了获取值对我来说有点奇怪。

EDIT: The idea behind this is that I would like to pass a list of arguments to a function (which accepts a named list for one of it's arguments) within the original function. 编辑:这背后的想法是,我想将参数列表传递给原始函数内的函数(该函数接受其中一个参数的命名列表)。 I'd like to capture values provided by the user, and default ones (for arguments where the user did not provide anything). 我想捕获用户提供的值和默认值(用于用户未提供任何内容的参数)。

I learned elsewhere that I can get all of that by a combination of match.call and formals . 我在其他地方学到,可以将match.callformals结合使用来获得所有这些。 But then, say I need to pass that to the query argument of the httr::GET function, and do some processing on it before I do so (such as adding " - " between "a" and "b"). 但是然后,说我需要将其传递给httr::GET函数的query参数,并在此之前对其进行一些处理(例如在“ a”和“ b”之间添加“-”)。 I then end up with something like "[ - letters - 1:2" instead of "a - b". 然后,我得到类似“ [-字母-1:2”而不是“ a-b”的内容。

I sense that if the answer is using eval , then I am probably asking the wrong question. 我感觉如果答案使用eval ,那么我可能会问错问题。

I sense that you are looking for something more general, so not sure if this is entirely what you are looking for but its simpler and gives you the desired result. 我感觉到您正在寻找更通用的东西,因此不确定这是否完全是您要寻找的东西,但它更简单并且可以为您提供所需的结果。 The critical piece here is do.call() 关键是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])

Well, I think you need to decide which part of your code needs evaluation and what needs not. 好吧,我认为您需要确定代码的哪些部分需要评估,哪些不需要。
It's not entirely clear from your example how general you want to go, but your example-question can be solved by a simple list(), you only need a custom function for providing defaults: 从您的示例中还不能完全清楚您想要的通用性,但是您可以通过一个简单的list()解决您的example-question问题,您只需要一个自定义函数即可提供默认值:

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= " - ")

Generally, you use match.call() without any arguments to find out in what way your function was called. 通常,您使用不带任何参数的match.call()来找出调用函数的方式。 Sometimes it's useful to know whether fun(a=c('a', 'b')) was called, or fun1(a = letters[1:2]), so match.call tells you this, without evaluating anything. 有时了解是否调用了fun(a = c('a','b'))或fun1(a =字母[1:2])很有用,所以match.call会告诉您这一点,而不进行任何评估。

So if you want to actually do something with your arguments, just call them directly, and you can later pass them on to another function 因此,如果您想对参数进行实际操作,只需直接调用它们,以后便可以将其传递给另一个函数

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

This function is just a variation on paste, but you can make it extensive as you want. 此功能只是粘贴的一种变体,但是您可以根据需要对其进行扩展。

And I get the impression that you want a general case where you match your arguments to the arguments of another function, but to answer that question I'd need to know more about what exactly you are trying to accomplish. 而且,我得到的印象是,您需要一个一般情况,即您将参数与另一个函数的参数进行匹配,但是要回答该问题,我需要更多地了解您到底想完成什么。

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

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