2012-01-05 5 views
27

Básicamente quiero cambiar una función no visible de un paquete. Para las funciones visibles, es decir, funciones que no tienen un asterisco cuando methods es llamado en ellos, me encontré con dos puestos de cómo podría lograr mi objetivo:¿Cómo anulo una función no visible en el espacio de nombres del paquete?

  1. Uso assignInNamespace: ver post en R-help.
  2. Uso fix: ver post en stackoverflow

Aunque ambos enfoques de trabajo para una función/visible exportado (utilizo predict.lm como un ejemplo más adelante para el segundo enfoque y probado el primer enfoque con la función subset.data.frame), no funcionan para una función no visible, por ejemplo predict.ar. ¿Porqué es eso? ¿Hay alguna solución?

Aquí está un ejemplo mínimo:

Demostrar que predict.lm es visible, no es 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* 

Aplicar 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 

Cambio predict.lm mediante la introducción de gato ("Primera línea modificada para predicción.lm \ n") al principio del cuerpo de la función. (Tienes que hacerlo manualmente en el 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 

Aplicar predict.ar:

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

tratar de cambiar 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 

intenta utilizar assignInNamespace lugar. (Tenga en cuenta que acaba de copiar la función stats:::predict.ar en un editor y añadí la línea cat("First line changed for predict.ar\n") al comienzo del cuerpo. Debido a que el cuerpo de la función es bastante largo, solamente muestro el primer par de líneas aquí)

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 

Desde "La primera línea modificada para predicción.ar" está realmente impresa en la consola, predec.ar debe haberse cambiado. Sin embargo, ¿por qué el objeto 'C_artoma' ya no se encuentra?

ACTUALIZACIÓN: OK, esto es muy vergonzoso, pero ya no puedo borrar esa publicación: La respuesta ya estaba en el enlace que brindé con la respuesta de Richie Cotton al final. ¡Lo siento por hacerte perder el tiempo! Creo que revisé todo y luego no veo lo obvio. ¿Podría alguien simplemente publicar esto como una respuesta y lo acepto? Lo siento de nuevo.

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

Respuesta

21

Usar fixInNamespace. :)

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

o

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

(Varios años más tarde ...)
Del comentario de Nicholas H: si desea insertar algún código en CRAN que dependa de una función interna de otro paquete, emitirá una advertencia de compilación y será rechazado por R-core. Si desea esa función interna, solo debe tomar una copia de la misma utilizando el operador ::: y mantenerla usted mismo.

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

OK, estoy muy enojado conmigo mismo por no revisar todos los eslabones de nuevo con precisión antes de la publicación (stackoverflow realmente necesita una opción de vista previa y la opción de downvote mismo ...), pero que en realidad el que da la respuesta correcta acaba de hacer mi día. ¡Así que gracias por eso! –

+7

@Christoph_J Proporciono un servicio de votación descendente por una tarifa. Si estás interesado ... :) –

+0

@ RomanLuštrik Haha, buena persona. Voy a pensar en ello y te haré saber pronto si estoy interesado ;-) –

Cuestiones relacionadas