使用match.call将所有参数传递给其他函数 [英] Use match.call to pass all arguments to other function

查看:285
本文介绍了使用match.call将所有参数传递给其他函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自?match.call:

match.call在两种情况下最常使用: […]将大部分调用传递给另一个函数[…]

match.call is most commonly used in two circumstances: […] To pass most of the call to another function […]

在阅读完这些内容后,我希望可以将match.call用于要将一个函数的所有参数传递给另一函数而又不逐一列出这些参数的情况.

After reading that, I expected I could use match.call when I want to pass all arguments of one function to another function without listing these arguments one by one.

示例:outer1逐个传递参数,outer2使用match.call.

Example: outer1 passes arguments one by one, outer2 uses match.call.

outer1 <- function(a, b, c) {
  inner1(a, b, c)
}

inner1 <- function(a, b, c) { 
  return(a + b + c$first + c$second)
}

outer2 <- function(a, b, c) {
   mycall <- match.call()
   inner2(mycall)
}

inner2 <- function(call) {
   return(call$a + call$b + call$c$first + call$c$second)
}

outer1(1, 2, list(first = 3, second = 4)) # OK: 10
outer2(1, 2, list(first = 3, second = 4)) # OK: 10

第一个问题出现在将-1而不是1传递给outer2时:

The first problem arises, when -1 instead of 1 is passed to outer2:

outer2(-1, 2, list(first = 3, second = 4)) # Error in call$a + call$b : non-numeric argument to binary operator

问题1 :传递-1而不是1有什么技术区别?我知道

Question 1: What is the technical difference between passing -1 instead of 1? I know that

typeof(quote(1)) # double
typeof(quote(-1)) # language

,但是我想我在第二种情况下传递了language对象的事实与(唯一)相关的区别不大,因为将类型语言的某些东西传递给参数c是可行的(typeof(quote(list(first = 3, second = 4))) # language).

but I suppose that the fact that I passed a language object in the second case is not the (only) relevant difference because passing something of type language to argument c works (typeof(quote(list(first = 3, second = 4))) # language).

为了克服上述问题,我尝试eval所有类型为language的参数:

In order to overcome the problem above, I try to eval all arguments that are of type language:

outer3 <- function(a, b, c) {

parsedCall <- lapply(match.call()[-1L], FUN=function(argument) {
    if(is.language(argument)) {
      return(eval(argument))
    } else {
      return(argument)
    }
  })

  inner3(parsedCall)
}

inner3 <- function(parsedCall) {  
  return(parsedCall$a + parsedCall$b + parsedCall$c$first + parsedCall$c$second)
}

outer3(-1, 2, list(first = 3, second = 4)) # OK: 8

问题2: outer3中的方法似乎行得通",但是我还需要考虑其他陷阱吗? (我知道在某些情况下,评估参数可能是不利的,但就我而言,这不应该成为问题.)

Question 2: The approach in outer3 seems to "work" but are there further pitfalls I need to take into account? (I know that in some cases it might be disadvantageous to evaluate the arguments but for my case this should not be an issue.)

问题3:我想将所有参数传递给另一个函数的愿望并不少见.有没有比我做的更好/标准的方法?

Question 3: I suppose that the desire to pass all arguments to another function is not very uncommon. Is there a better/standard approach than what I did?

问题4:将原始的call传递给内部函数是否有利,而其中的eval东西呢?如果我想将参数作为inner函数中的局部变量(而不是parsedCall列表中的元素),是否有帮助?然后,inner3的主体可能与inner1的主体相同(在当前解决方案中,我必须将a+b替换为parsedCall$a + parsedCall$b).

Question 4: Is it advantageous to pass the raw call to the inner function an do the eval stuff there? Would this be helpful if I would like to have the arguments as local variables in the inner functions (instead of elements of the parsedCall list)? Then, the body of inner3 could be identical to the body of inner1 (while with the current solution, I have to replace a+b with parsedCall$a + parsedCall$b).

推荐答案

关于您的问题:

我想将所有参数传递给另一个函数的愿望是 并不少见.有没有比我更好的/标准的方法 是吗?

I suppose that the desire to pass all arguments to another function is not very uncommon. Is there a better/standard approach than what I did?

那么我想说这是传递参数的一种更常见的方法:

Then I would say this is a more common way to pass the arguments on:

> inner1 <- function(a, b, c) { 
+   return(a + b + c$first + c$second)
+ }
> 
> outer3 <- function(a, b, c) {
+   mycall <- match.call()
+   mycall[[1]] <- as.symbol("inner1") # use inner 1
+   eval(mycall)
+ }
> 
> outer4 <- function(a, b, c) {
+   .args <- as.list(match.call()[-1]) # use inner 1
+   do.call(inner1, .args)
+ }
> 
> outer3(-1, 2, list(first = 3, second = 4))
[1] 8
> outer4(-1, 2, list(first = 3, second = 4))
[1] 8

这篇关于使用match.call将所有参数传递给其他函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆