假设我们有以下功能:
foo <- function(x)
{
line1 <- x
line2 <- 0
line3 <- line1 + line2
return(line3)
}
我们想要将第二行更改为:
line2 <- 2
你会怎么做?
一种方法是使用
fix(foo)
并更改功能。
另一种方法是再次编写该函数。
还有其他方法吗? (记住,任务是改变第二行)
我想要的是某种方式将函数表示为字符串(字符串)的向量,然后更改其中一个值,然后再将其转换为函数。
答案 0 :(得分:35)
> body(foo)[[3]] <- substitute(line2 <- 2)
> foo
function (x)
{
line1 <- x
line2 <- 2
line3 <- line1 + line2
return(line3)
}
(“{”是body(foo)[[1]],每一行都是列表的连续元素。)
答案 1 :(得分:23)
或者看看调试功能trace()
。它可能不是您正在寻找的,但它可以让您玩弄更改,并且它具有很好的功能,您可以随时使用untrace()
返回原始功能。
trace()
是base
软件包的一部分,附带一个完整且完整的帮助页面。
首先致电as.list (body(foo))
,查看代码的所有行。
as.list(body(foo))
[[1]]
`{`
[[2]]
line1 <- x
[[3]]
line2 <- 0
[[4]]
line3 <- line1 + line2
[[5]]
return(line3)
然后,您只需通过在trace()
中定义参数来定义要添加到函数中的内容以及放置它的位置。
trace (foo, quote(line2 <- 2), at=4)
foo (2)
[1] 4
我在开始时说trace()
可能不是您正在寻找的内容,因为您没有真正更改第三行代码,只是将值重新分配给对象line2
以下,插入代码行。如果您打印出现在跟踪的函数的代码
body (foo)
{
line1 <- x
line2 <- 0
{
.doTrace(line2 <- 2, "step 4")
line3 <- line1 + line2
}
return(line3)
}
答案 2 :(得分:20)
fix
是我知道这样做的最佳方式,尽管您也可以使用edit
并重新分配它:
foo <- edit(foo)
这是fix
内部的作用。如果要将更改重新分配给其他名称,可能需要执行此操作。
答案 3 :(得分:15)
fixInNamespace
与fix
类似。
答案 4 :(得分:8)
您可以使用'正文'功能。此函数将返回函数体:
fnx = function(a, b) { return(a^2 + 7*a + 9)}
body(fnx)
# returns the body of the function
因此,“编辑”函数的一个好方法是在赋值语句的左侧使用“body”:
body(fnx) = expression({a^2 + 11*a + 4})