Как увидеть исходный код функции R.Internal или .Primitive?

Ни один из них не показывает исходный код функции pnorm,

stats:::pnorm
getAnywhere(pnorm)  

Как я могу увидеть исходный код pnorm?

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

и, как я могу увидеть исходный код функции sum?

Ответ 1

Исходный код R pnorm:

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

Итак, технически говоря, ввод "pnorm" показывает вам исходный код. Однако более полезно: кишки pnorm закодированы на C, поэтому совет в предыдущем вопросе просмотр исходного кода в R полезен только для периферии (большинство из них концентрируется на функциях, скрытых в пространствах имен и т.д.).

Uwe Ligges статья в новостях R (стр. 43) является хорошей общей ссылкой. Из этого документа:

При взгляде на исходный код R иногда звонки к одной из следующих функций отображаются:.C(),.Call(),.Fortran(),.External() или .Internal() и .Primitive(). Эти функции вызывают точки входа в скомпилированном коде, таком как общие объекты, статические библиотеки или библиотеки динамических ссылок. Следовательно, необходимо изучить источники скомпилированного кода, если полное понимание кода обязательный.... Первым шагом является поиск точка входа в файл '$ R HOME/src/main/names.c, если вызывающая функция R является либо .Primitive(), либо .Internal(). Это выполняется в следующем примере для кода, реализующего "простую функцию R сумма().

(Акцент добавлен, потому что точная функция, о которой вы просили (sum), рассматривается в статье Ligges.)

В зависимости от того, насколько серьезно вы хотите вникнуть в код, возможно, стоит скачать и распаковывая исходный код, как предлагает Ligges (например, вы можете использовать инструменты командной строки например grep для поиска по исходному коду). Для более случайного осмотра вы можете просмотреть источники в Интернете через R сервер Subversion или Winston Chang github mirror (ссылки здесь специально относятся к src/nmath/pnorm.c). (Угадывая подходящее место для поиска, src/nmath/pnorm.c, немного разбирается в структуре исходного кода R.)

mean и sum реализованы в summary.c.

Ответ 2

Я знаю, что это сообщение больше двух лет, но я подумал, что это может быть полезно для некоторых пользователей, просматривающих этот вопрос.

Я в основном просто копирую свой ответ на этот другой аналогичный вопрос, чтобы он мог оказаться полезным некоторым пользователям R, которые хотят изучить исходные файлы C.

  • Во-первых, с помощью pryr вы можете использовать функцию show_c_source, которая будет искать в GitHub соответствующую часть кода в исходных файлах C. Работает для внутренних и. Примитивных функций.

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

    Что переносит вас в эту страницу, показывая, что unique.c содержит функцию do_matchcall.

  • Я собрал этот файл с разделителями табуляций, построенный на файле names.c и использующий find-in-files для определить местоположение исходного кода. Существуют некоторые функции, имеющие файлы, специфичные для платформы, и несколько других, для которых имеется более одного файла с соответствующим исходным кодом. Но для остальных отображение довольно хорошо установлено, по крайней мере для текущей версии (3.1.2).

Ответ 3

> 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>