需要帮助来理解这个R脚本

时间:2015-03-11 19:24:52

标签: r matlab

我是R的新手,所以如果有人帮我理解下面的脚本,我会很感激,所以我可以用Matlab写。 我只对" R"感兴趣此脚本的方法部分: 以下函数来自R中的copula包,它用于经验copula:

> F.n
function (x, X, offset = 0, method = c("C", "R")) 
{
    stopifnot(is.numeric(d <- ncol(X)), is.matrix(x), d == ncol(x))
    n <- nrow(X)
    if (d == 1) 
        vapply(x, function(x.) sum(X <= x.), NA_real_)/(n + offset)
    else {
        method <- match.arg(method)
        switch(method, C = {
            m <- nrow(x)
            .C(Cn_C, as.double(X), as.integer(n), as.integer(d), 
                as.double(x), as.integer(m), ec = double(m), 
                as.double(offset))$ec
        }, R = {
            tX <- t(X)
            vapply(1:nrow(x), function(k) sum(colSums(tX <= x[k, 
                ]) == d), NA_real_)/(n + offset)
        }, stop("wrong 'method': ", method))
    }
}
<environment: namespace:copula>

1 个答案:

答案 0 :(得分:3)

步行通过

function (x, X, offset = 0, method = c("C", "R")) 
{

带有两个必需参数和两个可选命名参数的函数定义。

    stopifnot(is.numeric(d <- ncol(X)), is.matrix(x), d == ncol(x))

这会产生一个断言(如果不是真的则退出),ncol(X)的返回是数字(它不是吗?),x是一个矩阵(2-dim数组),并且xX具有相同的列数。

    n <- nrow(X)

存储行数以备将来使用。 (nrow不是一个昂贵的功能,但这样做也没什么坏处。)

    if (d == 1) 
        vapply(x, function(x.) sum(X <= x.), NA_real_)/(n + offset)

X只有一列的情况下进行分支。

vapply函数迭代x的每个元素,将数字传递给内部函数,并将每个响应捕获到另一个向量中。 function(x.) ...是一个匿名或立即函数,在这种情况下被调用的次数与x中的元素一样多。 NA_real_是一种告诉vapply将返回什么类型的变量的方法; sapply可以清楚地工作(虽然不是那么快)。

生成的向量按元素n + offset进行划分,并从整个函数中返回。

    else {
        method <- match.arg(method)

这样可以确保method"C""R",或者该功能会出错。

以下switch类似于selectcase语句,如果method"C",它将执行第一个代码块,第二个if "R",否则将停止。

        switch(method, C = {
            m <- nrow(x)
            .C(Cn_C, as.double(X), as.integer(n), as.integer(d), 
                as.double(x), as.integer(m), ec = double(m), 
                as.double(offset))$ec

使用提供的参数调用名为Cn_C的C库函数,并从返回中提取ec组件。

        }, R = {
            tX <- t(X)

采用X的转置。

            vapply(1:nrow(x), function(k) sum(colSums(tX <= x[k, 
                ]) == d), NA_real_)/(n + offset)

(参见我上面对vapply的讨论。这一次是迭代一系列递增数字从1到x中的行数。)

对于匿名(内部)函数,从里到外,它首先将转置的Xx的第k行进行比较,从而得到一个布尔矩阵。在这种情况下,colSums仅仅计算来自该矩阵比较的每列中TRUE的数量。外部sum正在计算这些列式总和的数量,这些总和等于X中的列数(存储在d中,之前的版本)。

此向量按(n + offset)按元素分割,产生另一个向量。

        }, stop("wrong 'method': ", method))

如果在函数调用中向method提供了其他内容,则抛出异常。

    }
}

层的总结

如果你对矢量上的类似Map的函数不太熟悉,你真的应该对help(vapply)做更多的研究。阅读help(match.arg)help(switch)可能会让您受益匪浅。我认为其他主要功能(nrowncolt)足够清晰。

您可能不必担心.C(...)对函数库的调用,因为此函数也足以提供 R -native实现。 (嗯,这至少是我推断的。)