2012-01-05 4 views
27

Fondamentalmente voglio cambiare una funzione non visibile di un pacchetto. Per le funzioni visibili, cioè le funzioni che non hanno un asterisco quando methods si chiama su di loro, ho trovato due post come avrei potuto raggiungere il mio obiettivo:Come sovrascrivere una funzione non visibile nello spazio dei nomi del pacchetto?

  1. Uso assignInNamespace: vedi post su R-help.
  2. Uso fix: vedi post sul stackoverflow

Sebbene entrambi gli approcci di lavoro per una funzione/visibile esportata (uso predict.lm come esempio più avanti per il secondo approccio e testato il primo approccio con la funzione subset.data.frame), non funzionano per una funzione non visibile, ad es predict.ar. Perché? C'è una soluzione?

Ecco un esempio minimo:

Mostrare che predict.lm è visibile, non è predict.ar:

methods(predict) 
[1] predict.Arima*    predict.HoltWinters*  predict.StructTS*   
[4] predict.ar*    predict.arima0*   predict.glm    
[7] predict.lm     predict.loess*    predict.mlm    
[10] predict.nls*    predict.poly    predict.ppr*    
[13] predict.prcomp*   predict.princomp*   predict.smooth.spline*  
[16] predict.smooth.spline.fit* 

Applicare predict.lm:

x <- rnorm(5) 
y <- x + rnorm(5) 
predict(lm(y ~ x)) 
#   1   2   3   4   5 
# 1.0783047 1.5288031 0.3268405 0.8373520 -0.9833746 

Change predict.lm inserendo cat ("Prima riga modificata per predict.lm \ n") all'inizio del corpo della funzione. (È necessario farlo manualmente nell'editor):

fix(predict.lm) 
predict(lm(y ~ x)) 
# First line changed for predict.lm 
#   1   2   3   4   5 
# 1.0783047 1.5288031 0.3268405 0.8373520 -0.983374 

Applicare predict.ar:

sunspot.ar <- ar(sunspot.year) 
predict(sunspot.ar, n.ahead=25) 
# $pred 
# Time Series: 
# Start = 1989 
# End = 2013 

tenta di modificare predict.ar:

fix(predict.ar) #Here, an empty function body appears for me 
fix("stats:::predict.ar") #Here as well 
fix(stats:::predict.ar) 
#Error in fix(stats:::predict.ar) : 'fix' requires a name 

tenta di utilizzare assignInNamespace invece. (Si noti che ho appena copiato la funzione stats:::predict.ar in un editor e aggiunto la linea di cat("First line changed for predict.ar\n") all'inizio del corpo. Perché il corpo della funzione è piuttosto lunga, mostro solo il primo paio di righe qui)

mypredict <- function (object, newdata, n.ahead = 1, se.fit = TRUE, ...) 
{ 
    cat("First line changed for predict.ar\n") 
    if (n.ahead < 1) 
     stop("'n.ahead' must be at least 1") 
    #Rest of body of stats:::predict.ar 
} 
assignInNamespace("predict.ar", mypredict, ns="stats") 
predict(sunspot.ar, n.ahead=25) 
# First line changed for predict.ar 
# Error in predict.ar(sunspot.ar, n.ahead = 25) : 
# object 'C_artoma' not found 

Dal "La prima riga modificata per predict.ar" viene effettivamente stampata sulla console, prediction.ar deve essere stato modificato. Tuttavia, perché l'oggetto "C_artoma" non viene più trovato?

AGGIORNAMENTO: OK, questo è super imbarazzante, ma non riesco più a cancellare quel post: la risposta era già al link che ho fornito con la risposta di Richie Cotton alla fine. Scusa per aver perso tempo! Penso di aver controllato tutto e poi non vedo l'ovvio. Qualcuno potrebbe postare questo come risposta e io lo accetto. Ancora una volta mi dispiace.

fixInNamespace(predict.ar, pos="package:stats") 

risposta

21

Utilizzare fixInNamespace. :)

fixInNamespace("predict.ar", "stats") 

o

fixInNamespace("predict.ar", pos="package:stats") 

(Diversi anni dopo ...
Dal commento di Nicholas H: se si desidera inviare un codice a CRAN che dipende da una funzione interna di un altro pacchetto, genera un avviso di build e viene respinto da R-core. Se vuoi quella funzione interna, dovresti semplicemente prenderne una copia usando l'operatore ::: e mantenerla da solo.

predict.ar <- stats:::predict.ar 
+1

OK, io sono molto arrabbiato con me stesso per non controllare ogni link con precisione ancora prima dell'inserimento (StackOverflow davvero bisogno di un'opzione di anteprima e la possibilità di downvote voi stessi ...), ma che sono in realtà quello che dà la risposta corretta ha appena reso la mia giornata. Quindi grazie per quello! –

+7

@Christoph_J Sto fornendo un servizio di down-voting a pagamento. Se sei interessato ... :) –

+0

@ RomanLuštrik Haha, bravo. Ci penserò e ti farò sapere presto se sono interessato ;-) –

Problemi correlati