¿Cómo ver el código fuente de la función R .Internal o .Primitive?

81

Ninguno de estos muestra el código fuente de la pnormfunción,

stats:::pnorm
getAnywhere(pnorm)  

¿Cómo puedo ver el código fuente de pnorm?

sum
 (..., na.rm = FALSE)  .Primitive("sum")
.Primitive("sum")
function (..., na.rm = FALSE)  .Primitive("sum")
methods(sum)
no methods were found

y, ¿cómo puedo ver el código fuente de la sumfunción?

Bqsj Sjbq
fuente

Respuestas:

96

El código fuente de R pnormes:

function (q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) 
.Call(C_pnorm, q, mean, sd, lower.tail, log.p)

Entonces, técnicamente hablando, escribir "pnorm" le muestra el código fuente. Sin embargo, lo que es más útil: las entrañas de pnormestán codificadas en C, por lo que el consejo del código fuente de la vista de preguntas anterior en R solo es útil periféricamente (la mayoría se concentra en funciones ocultas en espacios de nombres, etc.).

El artículo de Uwe Ligges en R news (p. 43) es una buena referencia general. De ese documento:

Al mirar el código fuente de R, a veces aparecen llamadas a una de las siguientes funciones: .C (), .Call (), .Fortran (), .External () o .Internal () y .Primitive (). Estas funciones llaman puntos de entrada en código compilado, como objetos compartidos, bibliotecas estáticas o bibliotecas de enlaces dinámicos. Por lo tanto, es necesario buscar en las fuentes del código compilado, si se requiere una comprensión completa del código. ... El primer paso es buscar el punto de entrada en el archivo '$ R HOME / src / main / names.c', si la función R que llama es .Primitive () o .Internal (). Esto se hace en el siguiente ejemplo para el código que implementa la función R 'simple' sum ().

(Énfasis agregado porque la función precisa sobre la que preguntaste ( sum) está cubierta en el artículo de Ligges).

Dependiendo de la seriedad con la que desee profundizar en el código, puede valer la pena descargar y descomprimir el código fuente como sugiere Ligges (por ejemplo, puede usar herramientas de línea de comandos como grepbuscar en el código fuente). Para una inspección más informal, puede ver las fuentes en línea a través del servidor de R Subversion o el espejo github de Winston Chang (los enlaces aquí son específicamente para src/nmath/pnorm.c). (Adivinar el lugar correcto para buscar, src/nmath/pnorm.crequiere cierta familiaridad con la estructura del código fuente de R).

meany sumambos se implementan en resumen c .

Ben Bolker
fuente
1
está en una categoría diferente de pnorm. Prueba mean.defaultcon el código R y github.com/wch/r-source/blob/trunk/src/main/summary.c con el código C. ¡Y lea el artículo de Uwe Ligges vinculado arriba!
Ben Bolker
1
Solo para dar seguimiento a esta respuesta: es posible que deba tener cuidado con el nombre exacto de la función en C o Fortran también. Ejemplo: Yo estaba tratando de buscar el origen para el stlque llama a esta línea: z <- .Fortran(C_stl, x, n, as.integer(period), as.integer(s.window). Así que busqué en el espejo de Github vinculado anteriormente por la palabra clave C_stlsin éxito. Sin embargo, cuando busco stlhay un archivo llamado stl.fque es lo que quiero encontrar. La conclusión es que el nombre del archivo .co .f podría no ser exactamente el mismo que el nombre de la función que se está llamando.
Yuqli
35

Sé que esta publicación tiene más de 2 años, pero pensé que podría ser útil para algunos usuarios que navegan por esta pregunta.

Básicamente, estoy copiando mi respuesta a esta otra pregunta similar para que pueda resultar útil a algunos usuarios de R que quieran explorar los archivos fuente de C.

  1. Primero, con pryr puede usar la show_c_sourcefunción que buscará en GitHub el fragmento de código relevante en los archivos fuente de C. Funciona para funciones .Internal y .Primitive.

    body(match.call)
    
    # .Internal(match.call(definition, call, expand.dots))
    
    pryr::show_c_source(.Internal(match.call(definition, call, expand.dots)))
    

    Lo que lo lleva a esta página , mostrando que unique.ccontiene la función do_matchcall .

  2. He reunido este archivo delimitado por tabulaciones , basándose en el names.carchivo y usando buscar en archivos para determinar la ubicación del código fuente. Hay algunas funciones que tienen archivos específicos de la plataforma y un puñado de otras para las que hay más de un archivo con código fuente relevante. Pero por lo demás, el mapeo está bastante bien establecido, al menos para la versión actual (3.1.2).

Dominic Comtois
fuente
pryr no funciona cuando traté de localizar códigos C para system:, pryr::show_c_source(.Internal(system(x)))obtuveError: Could not find entry for system
zhanxw
7
> methods(mean)
[1] mean.data.frame mean.Date       mean.default    mean.difftime   mean.IDate*    
[6] mean.POSIXct    mean.POSIXlt    mean.yearmon*   mean.yearqtr*  

   Non-visible functions are asterisked
> mean.default
function (x, trim = 0, na.rm = FALSE, ...) 
{
    if (!is.numeric(x) && !is.complex(x) && !is.logical(x)) {
        warning("argument is not numeric or logical: returning NA")
        return(NA_real_)
    }
    if (na.rm) 
        x <- x[!is.na(x)]
    if (!is.numeric(trim) || length(trim) != 1L) 
        stop("'trim' must be numeric of length one")
    n <- length(x)
    if (trim > 0 && n) {
        if (is.complex(x)) 
            stop("trimmed means are not defined for complex data")
        if (any(is.na(x))) 
            return(NA_real_)
        if (trim >= 0.5) 
            return(stats::median(x, na.rm = FALSE))
        lo <- floor(n * trim) + 1
        hi <- n + 1 - lo
        x <- sort.int(x, partial = unique(c(lo, hi)))[lo:hi]
    }
    .Internal(mean(x))
}
<bytecode: 0x155ef58>
<environment: namespace:base>
IRTFM
fuente
Esto parece no responder a la pregunta original del OP (sobre pnorm), sino a su comentario a continuación sobre mean, y tenga en cuenta que esto también se incluye en el código C, en la parte inferior (consulte mi comentario a continuación).
Ben Bolker
2
En efecto. Y la "respuesta correcta" es la que dio antes ... lea el artículo de Uwe Ligges en RNews.
IRTFM