在 R 中有一个常见的函数调用模式,如下所示:
child = function(a, b, c) {
a * b - c
}
parent = function(a, b, c) {
result = child(a=a, b=b, c=c)
}
这种名称的重复很有帮助,因为如果要更改子参数的顺序,或者要在列表中添加其他变量,它可以防止潜在的潜在错误:
childReordered = function(c, b, a) { # same args in different order
a * b - c
}
parent = function(a, b, c) {
result = childReordered(a, b, c) # probably an error
}
但是当参数的名称变长时,这变得很麻烦:
child = function(longVariableNameA, longVariableNameB, longVariableNameC) {
longVariableNameA * longVariableNameB - longVariableNameC
}
parent = function(longVariableNameA, longVariableNameB, longVariableNameC) {
child(longVariableNameA=longVariableNameA, longVariableNameB=longVariableNameB, longVariableNameC=longVariableNameB)
}
我想有一种方法来获得命名参数的安全性,而无需再次实际键入名称。当我只能修改父母而不是孩子时,我希望能够做到这一点。我会设想这样的事情:
parent = function(a, b, c) {
result = child(params(a, b, c))
}
whereparams()
将是一个新函数,它根据变量的名称将未命名的参数转换为命名参数。例如:
child(params(c,b,a)) == child(a=a, b=b, c=c)
'pryr' 中有几个功能接近于此,但我还没有想出如何将它们结合起来做我想要的。 named_dots(c,b,a)
return list(c=c, b=b, a=a)
,并且standardise_call()
有类似的操作,但我还没有弄清楚如何能够将结果转换为可以传递给未修改的child()
.
我希望能够混合使用隐式和显式命名参数:
child(params(b=3, c=a, a)) == child(b=3, c=a, a=a)
能够混合一些未命名的常量(不是变量),并在传递给子进程时将它们视为命名参数也是很好的。
child(params(7, c, b=x)) == child(a=7, c=c, b=x) # desired
named_dots(7, c, b=x) == list("7"=7, c=c, b=x) # undesired
但是以非 R 的方式,我更愿意提出错误,而不是试图混淆可能的程序员错误:
child(params(c, 7, b=x)) # ERROR: unnamed parameters must be first
是否有已经存在的工具可以做到这一点?将现有功能拼凑起来做我想做的简单方法?更好的方法来实现在更改参数列表的情况下获得安全的相同目标而无需繁琐的重复?改进我建议的语法以使其更安全?
赏金前澄清:parent()
和child()
函数都应该被认为是不可更改的。我对使用不同的界面进行包装不感兴趣。相反,我在这里寻找一种以params()
通用方式编写提议函数的方法,该方法可以动态重写参数列表,以便两者都parent()
可以child()
直接使用安全但不冗长的语法。
赏金后澄清:虽然反转父子关系并使用 do.call() 是一种有用的技术,但它不是我在这里寻找的技术。相反,我正在寻找一种接受“...”参数的方法,将其修改为具有命名参数,然后以封闭函数将接受的形式返回它。正如其他人所暗示的那样,这可能真的是不可能的。就个人而言,我目前认为 C 级扩展是可能的,我希望这个扩展已经存在。也许vadr
包裹可以满足我的要求?https://github.com/crowding/vadr#dot-dot-dot-lists-and-missing-values
部分功劳:让赏金到期我觉得很傻。如果没有完整的解决方案,我会将其奖励给任何提供至少一个必要步骤的概念证明的人。例如,修改函数中的“...”参数,然后将其传递给另一个函数而不使用 do.call()。或者以父母可以使用的方式返回未修改的“...”参数。或者任何最能指出直接解决方案的方法,甚至是一些有用的链接:http ://r.789695.n4.nabble.com/internal-manipulation-of-td4682090.html 但我不愿意将其授予一个以“你不想这样做”或“那是不可能的,所以这是一个替代方案”为前提的(否则完全合理的)前提的答案。
赏金奖励:有几个非常有用且实用的答案,但我选择将赏金奖励给@crowding。虽然他(可能是正确的)断言我想要的是不可能的,但我认为他的回答最接近我所追求的“理想主义”方法。我还认为他的vadr包可能是解决方案的一个很好的起点,无论它是否符合我的(可能不切实际的)设计目标。如果有人想出一种方法来完成不可能的事情,那么“公认的答案”仍然有待商榷。感谢其他答案和建议,希望它们能帮助某人将这些部分组合在一起以获得更强大的 R 语法。