R .Internal 또는 .Primitive 함수의 소스 코드를 보는 방법은 무엇입니까?


81

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

답변:


96

의 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 에서 구현됩니다 .


1
와 다른 카테고리에 있습니다 pnorm. mean.defaultR 코드를 시도 하고 C 코드를 위해 github.com/wch/r-source/blob/trunk/src/main/summary.c 를 시도하십시오 . 그리고 위에 링크 된 Uwe Ligges의 기사를 읽어보세요!
Ben Bolker

1
이 답변에 대한 후속 조치를 취하려면 C 또는 Fortran의 정확한 함수 이름에 대해서도주의해야 할 수 있습니다. 예 : stl이 행을 호출 하는에 대한 소스를 찾으려고했습니다 z <- .Fortran(C_stl, x, n, as.integer(period), as.integer(s.window). 그래서 키워드 C_stl로 위에 링크 된 Github 미러를 검색했습니다 . 그러나 내가 검색 할 때 내가 찾고 싶은 stl파일이라는 파일 stl.f이 있습니다. 요점은 .c 또는 .f 파일 이름이 호출되는 함수 이름과 정확히 일치하지 않을 수 있다는 것입니다.
yuqli

35

이 게시물이 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)에 대해서는 매핑이 꽤 잘 확립되어 있습니다.


내가 C 코드를 찾으려고 할 때 pryr가 작동하지 않습니다 system: pryr::show_c_source(.Internal(system(x))), 나는Error: 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>

이것은 OP의 원래 질문 (about pnorm)에 대한 답변이 아닌 것 같지만 아래에 대한 의견 mean은 하단의 C 코드에도 적용됩니다 (아래 의견 참조).
Ben Bolker

2
과연. 그리고 "정답"은 이전에 제공 한 것입니다. RNews에서 Uwe Ligges의 기사를 읽어보십시오.
IRTFM 2012
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.