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

发布于 2024-12-01 00:19:09 字数 674 浏览 0 评论 0原文

我知道列表中的 NULL 值有时可以 绊倒人们。我很好奇为什么在特定实例中 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 的递归版本”,那么为什么它们在这种情况下的行为如此不同?

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

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

This example is very simple and non-recursive, but you see the same behavior in rapply with nested lists.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一念一轮回 2024-12-08 00:19:09

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

您不经常看到这种情况,但 NULL 实际上可以用来指示空序列,因为它是空的 pairlist (类似于 ()< /code> 在Scheme 中终止一个列表,R 在内部非常像scheme)。

因此,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;
}

I think you answered your own question: because it's recursive.

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).

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.

Actually, rapply and lapply don't really treat NULL that differently:

> lapply(NULL, identity)
list()

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文