[r] 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함수의 소스 코드를 어떻게 볼 수 있습니까?



답변

의 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”을 입력 하면 소스 코드 표시됩니다. 그러나 더 유용하게도 :의 내장은 pnormC로 코딩되었으므로 R 의 이전 질문 보기 소스 코드 의 조언은 주변 적으로 만 유용합니다 (대부분은 네임 스페이스 등에 숨겨진 함수에 집중합니다).

R 뉴스 (p. 43)에있는 Uwe Ligges의 기사 는 좋은 일반 참고 자료입니다. 해당 문서에서 :

R 소스 코드를 볼 때 .C (), .Call (), .Fortran (), .External () 또는 .Internal () 및 .Primitive () 함수 중 하나에 대한 호출이 표시되는 경우가 있습니다. 이러한 함수는 공유 객체, 정적 라이브러리 또는 동적 링크 라이브러리와 같은 컴파일 된 코드에서 진입 점을 호출합니다. 따라서 코드에 대한 완전한 이해가 필요한 경우 컴파일 된 코드의 소스를 살펴볼 필요가 있습니다. … 첫 번째 단계는 호출하는 R 함수가 .Primitive () 또는 .Internal () 인 경우 ‘$ R HOME / src / main / names.c’파일에서 진입 점을 찾는 것입니다. 이것은 ‘단순’R 함수 sum ()을 구현하는 코드에 대한 다음 예제에서 수행됩니다.

(당신이 질문 한 정확한 기능 ( sum)은 Ligges의 기사에서 다루기 때문에 강조가 추가되었습니다 .)

코드를 얼마나 심각하게 파헤 치고 싶은지에 따라 Ligges가 제안한대로 소스 코드를 다운로드하고 압축을 풀 가치가있을 수 있습니다 (예를 들어, grep소스 코드 검색 과 같은 명령 줄 도구를 사용할 수 있음 ). 좀 더 간단한 검사를 위해 R Subversion 서버 또는 Winston Chang의 github 미러 를 통해 온라인으로 소스를 볼 수 있습니다 (여기에있는 링크는 특히 src/nmath/pnorm.c). (보기에 적합한 위치를 추측하려면 src/nmath/pnorm.cR 소스 코드의 구조에 어느 정도 익숙해야합니다.)

mean그리고 sum둘 다 summary.c 에서 구현됩니다 .


답변

이 게시물이 2 년 이상 된 것을 알고 있지만이 질문을 탐색하는 일부 사용자에게 유용 할 것이라고 생각했습니다.

나는 기본적 으로이 다른 유사한 질문에 대한 내 대답을 복사 하여 C 소스 파일을 탐색하려는 일부 R 사용자에게 유용 할 수 있습니다.

  1. 첫째, pryr 를 사용하면 show_c_sourceGitHub에서 C 소스 파일의 관련 코드를 검색 하는 기능을 사용할 수 있습니다 . .Internal 및 .Primitive 함수에서 작동합니다.

    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 함수 가 포함되어 있음을 보여 줍니다 .

  2. 탭으로 구분 된 파일을 모아 파일을 기반 으로 빌드하고 names.c파일 에서 찾기를 사용 하여 소스 코드의 위치를 ​​결정했습니다. 플랫폼 별 파일이있는 일부 기능과 관련 소스 코드가있는 파일이 두 개 이상있는 일부 기능이 있습니다. 그러나 나머지는 적어도 현재 버전 (3.1.2)에 대해서는 매핑이 꽤 잘 확립되어 있습니다.


답변

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


답변