为什么rapply和lapply处理NULL的方式不同? [英] Why do rapply and lapply handle NULL differently?
问题描述
I'm aware that NULL values in lists can sometimes trip people up. I'm curious why in a specific instance lapply
and rapply
seem to treat NULL
values differently.
l <- list(a = 1, c = NULL, d = 3)
lapply(l,is.null)
$a
[1] FALSE
$c
[1] TRUE
$d
[1] FALSE
到目前为止,一切都很好.如果我们用rapply
做完全相同的事情怎么办?
So far so good. How about if we do the exact same thing with rapply
?
rapply(l, is.null, how = "replace")
$a
[1] FALSE
$c
list()
$d
[1] FALSE
此示例非常简单且非递归,但您在带有嵌套列表的rapply
中看到了相同的行为.
This example is very simple and non-recursive, but you see the same behavior in rapply
with nested lists.
我的问题是为什么?如果如?rapply
中所述,它是"lapply的递归版本",为什么在这种情况下它们的行为如此不同?
My question is why? If, as advertised in ?rapply
, it is a 'recursive version of lapply', why do they behave so differently in this case?
推荐答案
我认为您回答了自己的问题:因为它是递归的.
I think you answered your own question: because it's recursive.
您通常不会看到它,但是NULL
实际上可以用来表示一个空序列,因为它是空的pairlist
(类似于Scheme中()
终止列表的方式.在内部,R是很有计划).
You don't often see this, but NULL
can actually be used to indicate an empty sequence, because it is the empty pairlist
(similar to how ()
in Scheme terminates a list. Internally, R is very scheme like).
因此,rapply
递归到空列表中,但是完成后不会费心将其重新变成对列表;您会得到一个常规的空列表.
So, rapply
recurses into the empty list, but doesn't bother turning it back into a pairlist when it's done; you get a regular empty list.
实际上,rapply
和lapply
对待NULL的区别并不大:
Actually, rapply
and lapply
don't really treat NULL that differently:
> lapply(NULL, identity)
list()
您可以在R源代码中看到(内存. c ),这正是配对表的工作方式:
And you can see in the R source code (memory.c) that this is exactly how pairlists are meant to work:
SEXP allocList(int n)
{
int i;
SEXP result;
result = R_NilValue;
for (i = 0; i < n; i++)
result = CONS(R_NilValue, result);
return result;
}
这篇关于为什么rapply和lapply处理NULL的方式不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!