在R中的函数内通过(字符串)名称访问...函数参数?

时间:2016-09-25 18:38:21

标签: r

我正在尝试使用动态参数编写函数(即函数参数名称不是事先确定的)。在函数内部,我可以生成一个可能的参数名称列表作为字符串,并尝试使用相应的名称(如果给定)提取函数参数。我尝试使用match.arg,但这不起作用。

作为(大规模剥离)示例,请考虑以下尝试:

# Override column in the dataframe. Dots arguments can be any 
# of the column names of the data.frame.
dataframe.override = function(frame, ...) {
  for (n in names(frame)) {
    # Check whether this col name was given as an argument to the function
    if (!missing(n)) {
      vl = match.arg(n);
      # DO something with that value and assign it as a column:
      newval = vl
      frame[,n] = newval
    }
  }
  frame
}

AA = data.frame(a = 1:5, b = 6:10, c = 11:15)
dataframe.override(AA, b = c(5,6,6,6,6)) # Should override column b

不幸的是,match.arg显然不起作用:

  

match.arg(n)中的错误:'arg'应该是

之一

所以,我的问题是:在函数内部,我如何检查函数是否使用给定的参数调用并提取其值,并将参数名称作为字符串?

谢谢, 莱因霍尔德

PS:实际上,“做某事......”部分非常复杂,因此简单地将矢量直接分配给数据帧列而不需要这样的功能。

1 个答案:

答案 0 :(得分:1)

您可能希望查看Advanced-R中Non Standard Evaluation的章节。我也认为Hadley's answer to a related question可能有用。

所以:让我们从另一个答案开始吧。获取函数参数的最惯用方法是这样的:

get_arguments <- function(...){
    match.call(expand.dots = FALSE)$`...`
}

它提供了一个名为的参数列表

> get_arguments(one, test=2, three=3)
[[1]]
one

$test
[1] 2

$three
[1] 3

您只需在结果上调用names()即可获取姓名。

请注意,如果您希望将作为字符串,则需要使用deparse,例如

deparse(get_arguments(one, test=2, three=3)[[2]])
[1] "2"

P.S。您可能希望使用intersectsetdiff,而不是遍历所有列,例如

dataframe.override = function(frame, ...) {
  columns = names(match.call(expand.dots = FALSE)$`...`)[-1]
  matching.cols <- intersect(names(frame), names(columns))
  for (i in seq_along(matching.cols) {
    n = matching.cols[[i]]
    # Check whether this col name was given as an argument to the function
    if (!missing(n)) {
      vl = match.arg(n);
      # DO something with that value and assign it as a column:
      newval = vl
      frame[,n] = newval
    }
  }
  frame
}

P.P.S :我假设你没有使用dplyr::mutate这个原因。