我有一个函数f <- function(x){x}
。我想将行x <- 2*x
插入f
,以便最终为
function(x){
x <- 2*x
x
}
我知道我应该使用body()
,但到目前为止我只是想出了如何替换整个主体,这对我的真实目的来说是不切实际的。
答案 0 :(得分:4)
这是另一种方式(使用magrittr
来简化事情)
f <- function(x){x}
f(2)
# [1] 2
# library(magrittr)
body(f) <- body(f) %>% as.list %>% append(quote(x<-2*x), 1) %>% as.call
f(2)
# [1] 4
甚至只是
body(f) %<>% as.list %>% append(quote(x<-2*x), 1) %>% as.call %>% as.expression
但我觉得我可能会错过更简单的方式
你可以在没有magrittr
的情况下编写更传统的函数......
funins <- function(f, expr = expression(x<-2*x), after=1) {
body(f)<-as.call(append(as.list(body(f)), expr, after=after))
f
}
您可以使用它来插入任何表达式
f <- function(x){x}
g <- funins(f, expression(print("hi"), x<-3*x))
f(2)
# [1] 2
g(2)
# [1] "hi"
# [1] 6
答案 1 :(得分:3)
这是我的评论作为答案。如果它是单线功能的话,如果保护的话:
f <- function(x){x}
fun <- f
bod <- body(fun)
if (trimws(as.character(bod[[1]])) == "{"){
body(fun)[[2]] <- quote(x <- 2*x)
if (length(bod) > 1) body(fun)[3:(1+length(bod))] <- bod[-1]
} else {
body(fun)[[1]] <- as.name('{')
body(fun)[[2]] <- quote(x <- 2*x)
body(fun)[[3]] <- bod
}
fun
fun(3)
答案 2 :(得分:1)
f <- function(x) { x }
bdy <- deparse(body(f))
body(f) <- as.expression(parse(text=paste0(c(bdy[1], "x <- 2*x", bdy[2:3]), collapse="\n")))
了解你真正想做的事情将是gd。像这样的猴子修补功能听起来像个坏主意。
答案 3 :(得分:0)
以hrbrmstr的答案为基础,这是一个易于使用的包装器,无需使用外部软件包。
用于修补其他功能的功能。
patch.function <- function(fun, patch, position = 1) {
# Deparse the body.
fun.body <- deparse(body(fun))
# Append the patch to function body where intended.
patched.fun.body <- paste0(
c(fun.body[1:position], patch, fun.body[(position + 1):length(fun.body)]),
collapse = "\n"
)
# Parse and treat as an expression.
expr <- as.expression(parse(text = patched.fun.body))
return(expr)
}
假设我们要修补以下虚拟函数。
dummy.fun <- function() {
print("- a line A of the function body.")
print("- a line B of the function body.")
print("- a line C of the function body.")
print("- a line D of the function body.")
print("- a line E of the function body.")
print("- a line F of the function body.")
print("- a line G of the function body.")
print("- a line H of the function body.")
}
我们可以将其用作:
body(dummy.fun) <- patch.function(dummy.fun, "print('Before the A line of the body.')")
dummy.fun()
# Output:
# [1] "Before the A line of the body."
# [1] "- a line A of the function body."
# [1] "- a line B of the function body."
# [1] "- a line C of the function body."
# [1] "- a line D of the function body."
# [1] "- a line E of the function body."
# [1] "- a line F of the function body."
# [1] "- a line G of the function body."
# [1] "- a line H of the function body."
body(dummy.fun) <- patch.function(dummy.fun, "print('Before the D line of the body.')", position = 5)
dummy.fun()
# Output:
# [1] "Before the A line of the body."
# [1] "- a line A of the function body."
# [1] "- a line B of the function body."
# [1] "- a line C of the function body."
# [1] "Before the D line of the body."
# [1] "- a line D of the function body."
# [1] "- a line E of the function body."
# [1] "- a line F of the function body."
# [1] "- a line G of the function body."
# [1] "- a line H of the function body."