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

查看:20
本文介绍了使用 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])
  do.call(inner1, .args)
}

outer3(-1, 2, list(first = 3, second = 4))
#R> [1] 8

outer4(-1, 2, list(first = 3, second = 4))
#R> [1] 8

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

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