Заменить определение встроенной функции в R?
Пакет 'sparcl' использует функцию 'kmeans' в стандартном пакете 'stat'. Я хочу, чтобы вместо этого я использовал собственную реализацию 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
Так является ли редактирование кода пакета единственным способом?
Спасибо!
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:sparcl
) Ищу kmeans
первый в namespace:sparcl
затем в imports:sparcl
затем в namespace:base
а затем в .GlobalEnv
где он найдет ваш переопределенный kmeans
прежде чем он доберется до одного в package: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
Хорошо, функции из пакета статистики, которые используют kmeans()
не будет нарушен вашей версией, потому что они найдут kmeans
в их собственном пространстве имен, прежде чем поиск символов попадет в глобальную среду.
Если вы хотите отредактировать тело функции (но не ее аргументы) во время интерактивного сеанса, вы можете использовать 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()
в assignInNamespace()
и друзья, потому что untrace()
делает так легко отменить изменения.)