Saltar al contenido

¿Cómo puedo ver el código fuente de una función?

Este grupo de redactores ha pasado mucho tiempo buscando para dar soluciones a tu interrogante, te ofrecemos la soluciones por eso esperamos resultarte de mucha ayuda.

Solución:

UseMethod("t") te esta diciendo que t() es una función genérica (S3) que tiene métodos para diferentes clases de objetos.

El sistema de despacho del método S3

Para las clases S3, puede utilizar el methods función para enumerar los métodos para una función o clase genérica en particular.

> methods(t)
[1] t.data.frame t.default    t.ts*       

   Non-visible functions are asterisked
> methods(class="ts")
 [1] aggregate.ts     as.data.frame.ts cbind.ts*        cycle.ts*       
 [5] diffinv.ts*      diff.ts          kernapply.ts*    lines.ts        
 [9] monthplot.ts*    na.omit.ts*      Ops.ts*          plot.ts         
[13] print.ts         time.ts*         [<-.ts*          [.ts*           
[17] t.ts*            window<-.ts*     window.ts*      

   Non-visible functions are asterisked

"Las funciones no visibles están marcadas con un asterisco" significa que la función no se exporta desde el espacio de nombres de su paquete. Todavía puede ver su código fuente a través del ::: función (es decir stats:::t.ts), o usando getAnywhere(). getAnywhere() es útil porque no tiene que saber de qué paquete proviene la función.

> getAnywhere(t.ts)
A single object matching ‘t.ts’ was found
It was found in the following places
  registered S3 method for t from namespace stats
  namespace:stats
with value

function (x) 

    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)



El sistema de despacho del método S4

El sistema S4 es un sistema de envío de métodos más nuevo y es una alternativa al sistema S3. A continuación, se muestra un ejemplo de una función S4:

> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"

function (x, ...) 
standardGeneric("chol2inv")


Methods may be defined for arguments: x
Use  showMethods("chol2inv")  for currently available ones.

La salida ya ofrece mucha información. standardGeneric es un indicador de una función S4. El método para ver los métodos S4 definidos se ofrece de manera útil:

> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"

getMethod se puede utilizar para ver el código fuente de uno de los métodos:

> getMethod("chol2inv", "diagonalMatrix")
Method Definition:

function (x, ...) 

    chk.s(...)
    tcrossprod(solve(x))




Signatures:
        x               
target  "diagonalMatrix"
defined "diagonalMatrix"

También hay métodos con firmas más complejas para cada método, por ejemplo

require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"

Para ver el código fuente de uno de estos métodos, se debe proporcionar la firma completa, p. Ej.

getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )

No bastará con aportar la firma parcial

getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") : 
#  No method found for function "extract" and signature SpatialPolygons

Funciones que llaman a funciones no exportadas

En el caso de ts.union, .cbindts y .makeNamesTs son funciones no exportadas del stats espacio de nombres. Puede ver el código fuente de funciones no exportadas utilizando el ::: operador o getAnywhere.

> stats:::.makeNamesTs
function (...) 

    l <- as.list(substitute(list(...)))[-1L]
    nm <- names(l)
    fixup <- if (is.null(nm)) 
        seq_along(l)
    else nm == ""
    dep <- sapply(l[fixup], function(x) deparse(x)[1L])
    if (is.null(nm)) 
        return(dep)
    if (any(fixup)) 
        nm[fixup] <- dep
    nm



Funciones que llaman a código compilado

Tenga en cuenta que "compilado" no se refiere al código R compilado por bytes creado por el compilador paquete. los La línea en la salida anterior indica que la función está compilada por bytes y aún puede ver la fuente desde la línea de comando R.

Funciones que llaman .C, .Call, .Fortran, .External, .Internal, o .Primitive están llamando a puntos de entrada en código compilado, por lo que tendrá que mirar las fuentes del código compilado si desea comprender completamente la función. Este espejo de GitHub del código fuente de R es un lugar decente para comenzar. La función pryr::show_c_source puede ser una herramienta útil, ya que lo llevará directamente a una página de GitHub para .Internal y .Primitive llamadas. Los paquetes pueden usar .C, .Call, .Fortran, y .External; pero no .Internal o .Primitive, porque se utilizan para llamar a funciones integradas en el intérprete de R.

Las llamadas a algunas de las funciones anteriores pueden usar un objeto en lugar de un carácter string para hacer referencia a la función compilada. En esos casos, el objeto es de clase. "NativeSymbolInfo", "RegisteredNativeSymbol", o "NativeSymbol"; e imprimir el objeto proporciona información útil. Por ejemplo, optim llamadas .External2(C_optimhess, res$par, fn1, gr1, con) (nota que es C_optimhess, no "C_optimhess"). optim está en el paquete de estadísticas, por lo que puede escribir stats:::C_optimhess para ver información sobre la función compilada que se está llamando.

Código compilado en un paquete

Si desea ver el código compilado en un paquete, deberá descargar / descomprimir el código fuente del paquete. Los binarios instalados no son suficientes. El código fuente de un paquete está disponible en el mismo repositorio CRAN (o compatible con CRAN) desde el que se instaló originalmente el paquete. los download.packages() La función puede obtener la fuente del paquete por usted.

download.packages(pkgs = "Matrix", 
                  destdir = ".",
                  type = "source")

Esto descargará la versión fuente del paquete Matrix y guardará el correspondiente .tar.gz archivo en el directorio actual. El código fuente de las funciones compiladas se puede encontrar en el src directorio del archivo sin comprimir y sin tarar. El paso de descomprimir y desmarcar se puede realizar fuera de R, o desde dentro R utilizando el untar() función. Es posible combinar el paso de descarga y expansión en una sola llamada (tenga en cuenta que solo se puede descargar y desempaquetar un paquete a la vez de esta manera):

untar(download.packages(pkgs = "Matrix",
                        destdir = ".",
                        type = "source")[,2])

Alternativamente, si el desarrollo del paquete está alojado públicamente (por ejemplo, a través de GitHub, R-Forge o RForge.net), probablemente pueda buscar el código fuente en línea.

Código compilado en un paquete base

Ciertos paquetes se consideran paquetes "básicos". Estos paquetes se envían con R y su versión está bloqueada para la versión de R. Los ejemplos incluyen base, compiler, stats, y utils. Como tales, no están disponibles como paquetes descargables separados en CRAN como se describe arriba. Más bien, son parte del árbol de fuentes de R en directorios de paquetes individuales en /src/library/. En la siguiente sección se describe cómo acceder a la fuente R.

Código compilado integrado en el intérprete de R

Si desea ver el código integrado en el intérprete de R, deberá descargar / descomprimir las fuentes de R; o puede ver las fuentes en línea a través del repositorio de R Subversion o el espejo github de Winston Chang.

El artículo de noticias R de Uwe Ligges (PDF) (p. 43) es una buena referencia general de cómo ver el código fuente de .Internal y .Primitive funciones. Los pasos básicos son buscar primero el nombre de la función en src/main/names.c y luego busque el nombre de la "entrada C" en los archivos de src/main/*.

Además de las otras respuestas a esta pregunta y sus duplicados, aquí hay una buena manera de obtener el código fuente para una función de paquete sin necesidad de saber en qué paquete está. Por ejemplo, digamos si queremos la fuente para randomForest::rfcv():

Para ver edición en una ventana emergente:

edit(getAnywhere('rfcv'), file='source_rfcv.r')

View(getAnywhere('rfcv'), file='source_rfcv.r')

Tenga en cuenta que edit() abre un editor de texto (a elección del usuario), mientras que
View() invoca un visor de datos al estilo de una hoja de cálculo.

  • View() es ideal para navegar (multicolumnar) datos, pero generalmente terrible para código de cualquier otra longitud que no sea un juguete.
  • entonces cuando solo quiero ver código, edit() es la OMI en realidad mucho mejor que View(), ya que con edit() puede colapsar / ocultar / simular toda la lógica de análisis de argumentos / verificación / predeterminada / mensaje de error que puede tomar hasta el 70% de una función R, y simplemente llegar a la parte donde la función realmente operacionalmente hace algo (!) , qué tipo (s) de objetos es su tipo de retorno, si recurre y cómo, etc.

Para redirigir a un archivo separado (para que pueda abrir el código en su IDE / editor / procesarlo con grep / etc.):

capture.output(getAnywhere('rfcv'), file='source_rfcv.r')

Se revela cuando depura usando la función debug (). Suponga que desea ver el código subyacente en la función de transposición t (). Simplemente escribiendo 't', no revela mucho.

>t 
function (x) 
UseMethod("t")


Pero, usando el 'debug (functionName)', revela el código subyacente, sin los internos.

> debug(t)
> t(co2)
debugging in: t(co2)
debug: UseMethod("t")
Browse[2]> 
debugging in: t.ts(co2)
debug: 
    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)

Browse[3]> 
debug: cl <- oldClass(x)
Browse[3]> 
debug: other <- !(cl %in% c("ts", "mts"))
Browse[3]> 
debug: class(x) <- if (any(other)) cl[other]
Browse[3]>  
debug: attr(x, "tsp") <- NULL
Browse[3]> 
debug: t(x)

EDITAR:
debugonce () logra lo mismo sin tener que usar undebug ()

Reseñas y calificaciones del post

Si te ha sido útil este artículo, te agradeceríamos que lo compartas con el resto programadores de esta forma nos ayudas a difundir nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 3)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *