如何在不引起无限递归调用的情况下动态修改函数?

时间:2017-03-21 20:54:51

标签: r

我们假设我有一个函数f <- function(x) x + 2,我想修改它以返回之前返回的结果的一半。

我尝试f <- function(x) f(x) / 2导致无限递归调用(可预测)。

我提出了一个非常糟糕的解决方案:

f <- eval(parse(text = sprintf("function(x) {%s / 2}", 
                               paste0(deparse(body(f)), collapse = ""))))

有人有更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:4)

一般来说,修改一个功能的身体是混乱的。但是,对于compositiong(f(...)),可以处理:

body(f) <- as.call(list(as.symbol("/"), body(f), 2))
f 

# function (x) 
# (x + 2)/2

作为(危险)功能......

wrap <- function(f, g, ...){
    body(f) <<- as.call(list(as.symbol(g), body(f), ...))
}

f <- function(x) x + 2
wrap(f, "/", 2)
f
# function (x) 
# (x + 2)/2

答案 1 :(得分:2)

你想要这样的东西:

halvf <- function(f) {
    g <- f
    function(x) {
        g(x) / 2
    }
}

然后您可以执行以下操作:

x <- data.frame()
attr(x, "f") <- function(x) { x + 2 }
attr(x, "f")(2)
[1] 4
attr(x, "f") <- halvf(attr(x, "f"))
attr(x, "f")(2)
[1] 2
attr(x, "f") <- halvf(attr(x, "f"))
attr(x, "f")(2)
[1] 1
attr(x, "f") <- halvf(attr(x, "f"))
attr(x, "f")(2)
[1] 0.5