我正在尝试使用动态参数编写函数(即函数参数名称不是事先确定的)。在函数内部,我可以生成一个可能的参数名称列表作为字符串,并尝试使用相应的名称(如果给定)提取函数参数。我尝试使用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:实际上,“做某事......”部分非常复杂,因此简单地将矢量直接分配给数据帧列而不需要这样的功能。
答案 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。您可能希望使用intersect
或setdiff
,而不是遍历所有列,例如
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
这个原因。