我知道列表中的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的递归版本”,为什么在这种情况下它们的行为如此不同?

最佳答案

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

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

因此,rapply递归到空列表中,但是完成后不会费心将其重新变成对列表。您会得到一个常规的空列表。

实际上,rapplylapply对待NULL的区别并不大:

> lapply(NULL, identity)
list()


而且您可以在R源代码(memory.c)中看到,这正是配对表的工作方式:

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

关于r - 为什么rapply和lapply处理NULL的方式不同?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7170264/

10-12 16:43