5

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

一种方法是编辑 sparcl 包本身的代码。我宁愿避免这种情况,因为它会很混乱,而且我不确定如何在 R 中安装编辑后的代码。

不幸的是,超赋值运算符“<<-”不起作用:

> kmeans <<- function(x) print("hi!")
Error: cannot change value of locked binding for 'kmeans'

“分配”也没有:

assign("kmeans",function(x) {print("HI THERE!"); return(FALSE)},pos="package:sparcl")
Error in assign("is.null", function(x) { : 
  cannot add bindings to a locked environment

那么编辑包代码是唯一的方法吗?

谢谢!

4

2 回答 2

7

如果您确实想在交互式会话期间编辑函数的主体(而不是其参数),您可以使用trace(),如下所示:

trace("kmeans", edit=TRUE)

然后,在弹出的编辑器中,编辑正文,使其看起来像这样(例如):

function (x, centers, iter.max = 10, nstart = 1, algorithm = c("Hartigan-Wong", 
"Lloyd", "Forgy", "MacQueen")) 
{
    plot(rnorm(99), col = "red")
}

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

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

body(kmeans)  # To view the tracing code
kmeans()      # To use the edited function

最后,要恢复到未编辑的功能,只需执行untrace("kmeans"). (我通常更喜欢使用trace()toassignInNamespace()和friends,因为untrace()它可以很容易地撤消更改。)

于 2012-10-05T15:37:50.793 回答
2

进一步思考(并在重新阅读您的问题后),这是一个适合您的简单解决方案。

您需要做的就是将您编辑的版本分配给全局环境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)

这是有效的,因为KMeansSparseCluster()(和调用任何其他函数package:sparclkmeans 首先查找in namespace:sparcl然后in imports:sparcl然后in namespace:base,然后 in ,它会在它到达 in 之前.GlobalEnv找到您的重新定义。要自己看看,试试这个:kmeanspackage:stats

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

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

于 2012-10-05T17:14:20.467 回答