为什么rapply和lapply处理NULL不同?

时间:2011-08-24 03:57:53

标签: r null lapply

我知道列表中的NULL值有时可能会trip人。我很好奇为什么在特定实例中lapplyrapply似乎对NULL值的处理方式不同。

l <- list(a = 1, c = NULL, d = 3)

lapply(l,is.null)
$a
[1] FALSE

$c
[1] TRUE

$d
[1] FALSE

到目前为止一切顺利。如果我们使用rapply执行完全相同的操作怎么样?

rapply(l, is.null, how = "replace")
$a
[1] FALSE

$c
list()

$d
[1] FALSE

此示例非常简单且非递归,但您在rapply中看到了与嵌套列表相同的行为。

我的问题是为什么?如果像?rapply中所宣传的那样,它是“lapply的递归版本”,为什么它们在这种情况下表现得如此不同?

1 个答案:

答案 0 :(得分:20)

我认为你回答了自己的问题:因为它是递归的。

您通常不会看到这一点,但NULL实际上可用于指示空序列,因为它是空的pairlist(类似于Scheme中()的终止方式列表。在内部,R非常类似于计划。

所以,rapply递归到空列表中,但是当它完成时,它不会把它变回一个pairlist;你得到一个常规的空列表。

实际上,rapplylapply并没有真正区别对待NULL:

> lapply(NULL, identity)
list()

你可以在R源代码(memory.c)中看到,这正是pairlists的工作方式:

SEXP allocList(int n)
{
    int i;
    SEXP result;
    result = R_NilValue;
    for (i = 0; i < n; i++)
        result = CONS(R_NilValue, result);
    return result;
}