替换R中内置函数的定义?

替换R中内置函数的定义?,r,function,package,R,Function,Package,“sparcl”包使用标准“stat”包中的“kmeans”函数。我想让它改用我自己的kmeans++实现 一种方法是编辑sparcl包本身中的代码。我宁愿避免这种情况,因为这样会很混乱,也因为我不确定接下来如何在R中安装经过编辑的代码 不幸的是,superassignment运算符“如果您确实希望在交互式会话期间编辑函数体(而不是其参数),则可以使用trace(),如下所示: trace("kmeans", edit=TRUE) 然后,在弹出的编辑器中,编辑主体,使其看起来像这样(例如):

“sparcl”包使用标准“stat”包中的“kmeans”函数。我想让它改用我自己的kmeans++实现

一种方法是编辑sparcl包本身中的代码。我宁愿避免这种情况,因为这样会很混乱,也因为我不确定接下来如何在R中安装经过编辑的代码


不幸的是,superassignment运算符“如果您确实希望在交互式会话期间编辑函数体(而不是其参数),则可以使用
trace()
,如下所示:

trace("kmeans", edit=TRUE)
然后,在弹出的编辑器中,编辑主体,使其看起来像这样(例如):

保存已编辑的函数定义,然后退出编辑器

回到R命令行,您可以查看已编辑的函数并进行尝试:

body(kmeans)  # To view the tracing code
kmeans()      # To use the edited function
最后,要恢复到未编辑的函数,只需执行
untrace(“kmeans”)
(我通常更喜欢使用
trace()
,而不是
assignInNamespace()
和friends,因为
untrace()
使撤销更改变得非常容易。)

经过进一步思考(并在重新阅读您的问题后),这里有一个简单的解决方案,应该适合您

您所需要做的就是将您编辑的
kmeans()
版本分配给全局环境中的符号
kmeans
。换句话说,在命令行执行以下操作:

kmeans <- function(...) plot(rnorm(99), col="red") # but using your own edits

## Then run an example from ?KMeansSparseCluster to see that it works.
library(sparcl)
x <- matrix(rnorm(50*300),ncol=300)
x[1:25,1:50] <- x[1:25,1:50]+1
x <- scale(x, TRUE, TRUE)
KMeansSparseCluster.permute(x,K=2,wbounds=seq(3,9,len=15),nperms=5)

很好,stats包中使用
kmeans()的函数
不会被你的版本打乱,因为在符号搜索进入全局环境之前,他们会在自己的命名空间中找到
kmeans

你能使用
trace
吗?你为什么要替换旧版本,而不是只编写一个新版本,然后使用那个版本?不是吗更容易创建调用
kmeans
的(导出)函数的您自己的版本,并修改这些实例,以便它们调用您自己的自定义函数?(也许@Dason也是这么说的…?)我支持@joran的建议。如果您确实想打包函数,请创建您自己的迷你包(可能从统计数据导入)与其编辑统计数据包的源代码!@joran的建议并不完美,因为sparcl包中的多个文件中的多个函数多次调用了
kmeans
,所以我还必须复制和编辑所有这些数据包……但我最初计划就是这样做的。谢谢,我不知道trace()。虽然我认为它不能完全解决我的问题,因为sparcl包在不同的函数中对kmeans进行了大量调用…@martas可能只是获取包的源代码,使用一个好的文本编辑器更改
kmeans
调用的所有实例不会花费太多时间,然后在本地重建包。我认为人们只是对覆盖stats包代码本身的解决方案有点怀疑,你可能会在以后后悔。
trace()
名称空间:stats
中编辑函数,因此它将编辑任何调用它的函数看到的
kmeans()
版本。这不是你想要的吗,还是我感到困惑?(不是相互排斥的可能性,我知道…)上帝之母,它(你的编辑)起作用了!谢谢。我想这起作用是因为kmeans不是sparcl代码显式导入的包的一部分,对吗?我仍然非常不了解R处理名称空间的方式…@martas--Oops。你可能想把“接受”移到我的另一个答案。(我认为它与上一个答案有很大的不同,所以我应该将其拆分。我本来会覆盖上一个答案re:trace,但它本身看起来可能很有用。)@JoshOBrien:难道这个包不可能专门从统计包中导入
kmeans
,所以它应该是在
imports:sparcl
中吗?这是“正确”的方法,是吗?@Aaron——我同意:这是正确的方法,但不是sparcl的作者所做的是的。我检查了
imports:sparcl
,它是空的。但是,你的大点是一个好的点。如果包作者将
import(“stats”)
放在他们的命名空间文件中,这个解决方案将不起作用。感谢更新,Josh。检查
imports:sparcl
中的内容很好。
function (x, centers, iter.max = 10, nstart = 1, algorithm = c("Hartigan-Wong", 
"Lloyd", "Forgy", "MacQueen")) 
{
    plot(rnorm(99), col = "red")
}
body(kmeans)  # To view the tracing code
kmeans()      # To use the edited function
kmeans <- function(...) plot(rnorm(99), col="red") # but using your own edits

## Then run an example from ?KMeansSparseCluster to see that it works.
library(sparcl)
x <- matrix(rnorm(50*300),ncol=300)
x[1:25,1:50] <- x[1:25,1:50]+1
x <- scale(x, TRUE, TRUE)
KMeansSparseCluster.permute(x,K=2,wbounds=seq(3,9,len=15),nperms=5)
parent.env(asNamespace("sparcl"))
parent.env(parent.env(asNamespace("sparcl")))
parent.env(parent.env(parent.env(asNamespace("sparcl"))))
## etc., also wrapping any of the environments above in calls to ls() 
## to see what's in 'em