我们假设我有一个函数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 = ""))))
有人有更优雅的解决方案吗?
答案 0 :(得分:4)
一般来说,修改一个功能的身体是混乱的。但是,对于composition,g(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