如何查看R .Internal或.Primitive函数的源代码?

Bqs*_*jbq 77 r

这些都没有显示pnorm功能的源代码,

stats:::pnorm
getAnywhere(pnorm)  
Run Code Online (Sandbox Code Playgroud)

我怎么能看到源代码pnorm

sum
 (..., na.rm = FALSE)  .Primitive("sum")
.Primitive("sum")
function (..., na.rm = FALSE)  .Primitive("sum")
methods(sum)
no methods were found
Run Code Online (Sandbox Code Playgroud)

而且,我怎样才能看到该sum函数的源代码?

Ben*_*ker 90

R源代码pnorm是:

function (q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) 
.Call(C_pnorm, q, mean, sd, lower.tail, log.p)
Run Code Online (Sandbox Code Playgroud)

因此,从技术上讲,输入"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()的代码,在以下示例中完成此操作.

(强调之所以增加是因为你所提到的关于(sum)的确切功能在Ligges的文章中有所涉及.)

根据您想要深入研究代码的程度,可能值得下载和解压缩源代码,如Ligges所建议的那样(例如,您可以使用命令行工具,例如grep搜索源代码).对于更随意的检查,您可以通过R Subversion服务器Winston Chang的github镜像在线查看源(这里的链接是专门的src/nmath/pnorm.c).(猜测正确的地方src/nmath/pnorm.c,需要熟悉R源代码的结构.)

mean并且sum都在summary.c中实现.


Dom*_*ois 31

我知道这篇文章已经超过2年了,但我认为这可能对浏览这个问题的一些用户有用.

我基本上只是将我的答案复制到另一个类似的问题,这样对于想要探索C源文件的R用户来说它可能会有用.

  1. 首先,使用pryr,您可以使用show_c_source将在GitHub上搜索C源文件中相关代码段的函数.适用于.Internal和.Primitive函数.

    body(match.call)
    
    # .Internal(match.call(definition, call, expand.dots))
    
    pryr::show_c_source(.Internal(match.call(definition, call, expand.dots)))
    
    Run Code Online (Sandbox Code Playgroud)

    这将带你到这个页面,显示unique.c包含函数do_matchcall.

  2. 我已经将这个制表符分隔文件放在一起,构建在names.c文件上并使用find-in-files来确定源代码的位置.有些函数具有特定于平台的文件,还有一些函数具有多个具有相关源代码的文件.但对于其余部分,映射已经很好地建立,至少对于当前版本(3.1.2)而言.


42-*_*42- 6

> 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>
Run Code Online (Sandbox Code Playgroud)

  • 的确。而“正确答案”就是您之前给出的答案……阅读 RNews 上 Uwe Ligges 的文章。 (2认同)