我知道列表中的NULL值有时可以trip使人烦恼。我很好奇为什么在特定实例中lapply
和rapply
似乎将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
递归到空列表中,但是完成后不会费心将其重新变成对列表。您会得到一个常规的空列表。
实际上,rapply
和lapply
对待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/