我想在我的包中提供一个名为“Sdt”的函数。它有多种方法,但它们都会导致Sdt.default(a,b,c,d),它会返回一个带有a,b,c和d的计算内容的命名向量。
但在某些情况下,我的软件包的用户需要扩展Sdt.default,例如,如果他/她想要尝试使用这四个变量进行其他一些计算。
所以我想:为什么不暂时覆盖这个功能?所以我尝试了类似的东西(当然是Sdt,但这是一个更好的玩具示例):
a <- function() print("FUNCTION A CALLED")
b <- function() print("FUNCTION B CALLED")
c <- function() a()
d <- function(){
a()
a <- b
a()
c()
}
d()
结果如下
[1] "FUNCTION A CALLED"
[1] "FUNCTION B CALLED"
[1] "FUNCTION A CALLED"
但我想要
[1] "FUNCTION A CALLED"
[1] "FUNCTION B CALLED"
[1] "FUNCTION B CALLED"
“&lt;&lt; - ”运算符可以在这个例子中工作,但是如果在包中定义了一个(),它会抛出错误消息,(“包中确定的函数不能被改变”或类似的东西)那)
TL; DR 如何暂时但完整地从包中的函数覆盖全局环境中的函数,以便所有后续和嵌套调用都使用更改的函数?
答案 0 :(得分:3)
我不会同时使用assign
或<<-
。我只想修改c()
函数
a <- function() print("FUNCTION A CALLED")
b <- function() print("FUNCTION B CALLED")
c <- function(x = a) x()
d <- function(){
a()
a <- b
a()
c(a)
}
d()
## [1] "FUNCTION A CALLED"
## [1] "FUNCTION B CALLED"
## [1] "FUNCTION B CALLED"
虽然没有参数的c()
可以使用相同的
c()
## [1] "FUNCTION A CALLED"
答案 1 :(得分:3)
我是@ DavidArenburg解决方案的粉丝,但是如果要为所有要暂时覆盖的变量定义默认参数不是一个选项,这是另一种方式:
d <- function(){
a()
a <- b
a()
environment(c) <- environment()
c()
}
d()
# [1] "FUNCTION A CALLED"
# [1] "FUNCTION B CALLED"
# [1] "FUNCTION B CALLED"
c()
# [1] "FUNCTION A CALLED"
答案 2 :(得分:1)
您可以使用assign
功能将新创建的功能放入全局环境中
看看这个示例替换基本sum
函数:
callSum <- function() sum(1)
main <- function(){
# here we use the original sum function -> we expect 1
print(sum(1))
# let's create a new sum function returning always 100
# and assign it to the global env. with name "sum"
# (note that the name of this function object is not important,
# but the name used in assign is crucial)
newSum <- function(v) {return(100)}
assign("sum", newSum, envir=globalenv())
# let's call sum(1) -> we expect 100
print(sum(1))
# let's call a function that calls sum(1) -> we expect 100
print(callSum())
# we don't want to return anything...
invisible()
}
main()
打印:
[1] 1
[1] 100
[1] 100
但是,这不是一个干净的解决方案。
如果您认为需要经常在软件包实现和自定义实现之间切换,我建议创建一个Std
的包装器,并在需要使用Std
函数的任何地方使用它。这样,当您想要停止使用包版本时,您只需更改包装器实现,例如:
StdWrapper <- function(a,b,c,d){
return(Std(a,b,c,d))
# return(YourCustomStd(a,b,c,d))
# as soon as you need to switch to a custom implementation,
# just comment the first line and uncomment the second and vice-versa
}