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

时间:2012-12-26 02:49:59

标签: r

这些都没有显示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函数的源代码?

3 个答案:

答案 0 :(得分:87)

pnorm的R源代码是:

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编写的,所以上一个问题view source code in R中的建议只是外围有用(大多数都集中在隐藏在命名空间中的函数等)。

Uwe Ligges的article in R news(第43页)是一个很好的一般参考。从该文件:

  

查看R源代码时,有时会调用   显示以下功能之一:.C(),   .Call(),.Fortran(),. External()或.Internal()   和.Primitive()。这些函数调用编译代码中的入口点,例如共享对象,   静态库或动态链接库。因此,   如果完全理解代码,有必要查看已编译代码的来源   需要。   ...   第一步是查找   文件'$ R HOME / src / main / names.c'中的入口点,如果   调用R函数是.Primitive()或   。内部()。 这在以下示例中针对实现“简单”R函数的代码完成   总和()。

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

根据您想要深入了解代码的程度,可能值得下载和 像Ligges建议的那样解压缩源代码(例如,你可以使用命令行工具 例如grep来搜索源代码)。对于更随意的检查,您可以查看 来自R Subversion serverWinston Chang's github mirror的在线来源(此处的链接专门针对src/nmath/pnorm.c)。 (猜测正确的地方,src/nmath/pnorm.c,需要熟悉R源代码的结构。)

meansum都在summary.c中实施。

答案 1 :(得分:29)

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

我基本上只是将我的答案复制到this other similar question,以便它可能对某些想要浏览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)))
    

    这会将您带到this page,表明unique.c包含do_matchcall函数。

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

答案 2 :(得分: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>