Nadpisuje funkcję importowaną w przestrzeni nazw
Ponieważ termplot
Funkcja W R zawiera jakiś dziwny kod, który powoduje irytujące błędy, chcę ją nadpisać w moim własnym kodzie testowym, dopóki nie znajdę bardziej trwałego rozwiązania. Problem polega na tym, że zmieniona funkcja nie jest ładowana przez pakiet mgcv
. Pakiet mgcv
ładuje termplota z pakietu stats w jego przestrzeni nazw, używając importFrom()
w pliku przestrzeni nazw.
Jak mogę przekonać mgcv do użycia zmienionego termplot? Próbowałem:
unlockBinding("termplot", as.environment("package:stats"))
assign("termplot", my.termplot, as.environment("package:stats"))
lockBinding("termplot", as.environment("package:stats"))
I po zastosowaniu do obiektów lm działa to i zmieniony termplot jest używany. Ale podczas korzystania z obiektów gam wykonanych przez pakiet mgcv, to nie działa. Nie zamierzam budować pakietu statystyk ze źródła, jeśli mogę go uniknąć...
Aby wyjaśnić, próbowałem również z
assignInNamespace("termplot", my.termplot, ns="stats")
assignInNamespace("termplot", my.termplot, ns="mgcv")
We wszystkich możliwych kombinacjach, przed podłączeniem mgcv, po podłączeniu mgcv i nie udało mi się go uruchomić.
EDIT:
Wypróbowałem wszystkie podane tutaj opcje (poza przebudową obu pakietów) i nie mogłem go uruchomić. Łatwym wyjściem dla mnie jest użycie funkcji owijania. Tę dyskusję można znaleźć tutaj . Dzięki za wszystkie wskazówki.
Powtarzalny przykład:
my.termplot <- function (x) print("my new termplot")
unlockBinding("termplot", as.environment("package:stats"))
assignInNamespace("termplot", my.termplot, ns="stats", envir=as.environment("package:stats"))
assign("termplot", my.termplot, as.environment("package:stats"))
lockBinding("termplot", as.environment("package:stats"))
y <- 1:10
x <- 1:10
xx <- lm(y~x)
termplot(xx)
require(mgcv)
dat <- gamSim(1, n = 400, dist = "normal", scale = 2)
b <- gam(y ~ s(x0) + s(x1) + s(x2) + x3, data = dat)
plot(b,all=TRUE)
plot.gam
wywołuje termplot dla nie-gładkich terminów (w tym przypadku x3), ale nie znajduje nowej funkcji termplot.
EDIT2: najwyraźniej mój przykład działa. Widzę teraz rozwiązałem własne pytanie: w pierwszym kodzie nie dodałem zarówno przestrzeni nazw, jak i pakietu w assignInNamespace. Ważne jest, aby pamiętaj, aby zmienić funkcję zarówno w przestrzeni nazw, jak i pakietu przed załadowaniem drugiego pakietu. Thx @hadley za wskazanie mi właściwego kierunku, @Marek za testowanie kodu i zgłoszenie, że działa, a reszta za podjęcie wysiłku, aby odpowiedzieć. [odpowiedz]
3 answers
Jestem zakłopotany - nie mogę rozgryźć, jak plot.gam
lokalizuje termplot
- z tego, co wiem, nie używa zwykłych zasad przeszukiwania. Wydaje się, że wymaga to głębszego zrozumienia przestrzeni nazw niż obecnie posiadam.
my.termplot <- function (x) print("my new termplot")
# where is it defined?
getAnywhere("termplot")
# in package and in namespace
unlockBinding("termplot", as.environment("package:stats"))
assign("termplot", my.termplot, "package:stats")
unlockBinding("termplot", getNamespace("stats"))
assign("termplot", my.termplot, getNamespace("stats"))
getAnywhere("termplot")[1]
getAnywhere("termplot")[2]
# now changed in both places
y <- 1:10
x <- 1:10 + runif(10)
xx <- lm(y ~ x)
termplot(xx) # works
library("mgcv")
b <- gam(y ~ s(x), data = data.frame(x, y))
plot(b) # still calls the old termplot
# I'm mystified - if try and find termplot as
# seen from the environment of plot.gam, it looks
# like what we want
get("termplot", environment(plot.gam))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-09 05:17:29
Spróbuj nadpisać funkcję, z której wywołujesz termplot
. Domyślam się, że jest to plot.gam
w mgcv
pakiecie.
Najpierw załaduj niezbędny pakiet.
library(mgcv)
Oto Twoja alternatywna Funkcja termplot
, dodana do przestrzeni nazw stats
.
my.termplot <- function (model, ...)
{
message("In my.termplot")
}
unlockBinding("termplot", as.environment("package:stats"))
assign("termplot", my.termplot, as.environment("package:stats"))
lockBinding("termplot", as.environment("package:stats"))
Podobnie, oto funkcja wrapper, dodana do przestrzeni nazw mgcv
.
my.plot.gam <- function (x, ...)
{
message("In my.plot.gam")
my.termplot()
}
unlockBinding("plot.gam", as.environment("package:mgcv"))
assign("plot.gam", my.plot.gam, as.environment("package:mgcv"))
lockBinding("plot.gam", as.environment("package:mgcv"))
Oto przykład do przetestowania, zaczerpnięty z ?gam
.
dat <- gamSim(1, n = 400, dist = "normal", scale = 2)
b <- gam(y ~ s(x0) + s(x1) + s(x2) + s(x3), data = dat)
plot(b)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-06 17:17:50
Myślę, że funkcja trace() wykonuje automatycznie to, co zostało opisane powyżej. Do:
trace('termplot', edit='gedit')
Gdzie 'gedit' to nazwa edytora tekstu. Edytor otworzy się z oryginalnym kodem i możesz wkleić dowolny kod zastępczy, który chcesz.
Aby powrócić do oryginalnej wersji wystarczy untrace ('termplot')
Zastrzeżenie: próbowałem tego użyć, gdy edytor tekstu miał wiele otwartych plików i nie działał. Używam więc "gedit", edytora tekstu w moim systemie, którego nie używam często. Tędy. Jestem pewien, że R otworzy nową instancję "gedit".
Nie jestem pewien, czy to pomoże, ale myślę, że warto spróbować. Sekwencja wyszukiwania, gdy istnieją przestrzenie nazw, jest naprawdę myląca.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-06 19:47:16