【问题标题】:different behaviors when passing empty ellipsis arguments传递空省略号参数时的不同行为
【发布时间】:2023-04-01 10:34:01
【问题描述】:

This answer 提出了R 中的省略号功能如何处理空参数的问题。显然,... 中的空参数有时有效(参见下面的 lapply 版本),但在其他时候无效(参见 sapply 版本)。示例如下:

lst <- list(x=matrix(1))
lapply(lst, "[", 1, )
# $x
# [1] 1
sapply(lst, "[", 1, )
# Error in lapply(X = X, FUN = FUN, ...) : 
#   argument is missing, with no default

据我所知,sapply 实际上只是在调用lapply 时重用了它的... 参数。所以我不明白为什么lapply 有效但sapply 无效。任何人都可以解释这种行为。

sapply 帮助中指出

sapply(*, simple = FALSE, USE.NAMES = FALSE) 等价于 lapply(*)。

但是,对于以下内容,我得到与上述相同的结果:

lapply(lst, "[", i=1, j=)
sapply(lst, "[", i=1, j=, simplify=FALSE, USE.NAMES=FALSE)

顺便说一句,我知道在这种情况下,只需添加TRUE 就可以解决问题,但我更感兴趣的是为什么会有差异,而不是如何解决它。实际上,我更惊讶它适用于lapply 的情况,而不是不适用于sapply 的情况。

【问题讨论】:

  • 我猜它不是特定于 sapply 而是特定于任何 lapply 包装器:(function(X, FUN, ...) lapply(X, FUN, ...))(lst, "[", 1, );也许,它与?lapply 中的“历史原因”注释有关,而它的包装器必须评估他们的论点?
  • 你看过 sapply 和 lapply 的源代码吗?
  • @JamesTobin:我查看了源代码的 R 部分。 sapply 真的只是调用lapply (此时它失败了)然后简化了结果。 lapply 调用 .Internal(lapply(X, FUN)),我还没有看过它的源代码。 lapply 似乎也根本没有使用...(?)但似乎在sapply 调用和lapply 调用之间以某种方式... 的含义发生了变化。

标签: r lapply


【解决方案1】:

因为我根本不是 C 大师,所以我只能告诉你 sapplylapply 内部表示的区别是什么。也许其他人可以在这个答案的基础上再做一点。

所以对于sapply:我们将看看https://github.com/SurajGupta/r-source/blob/master/src/library/base/R/sapply.R

对于 lapply:https://github.com/SurajGupta/r-source/blob/master/src/library/base/R/lapply.R

这表明虽然sapply 调用lapply 然后它也调用simplify2array 这可能是问题之一,但我的直觉告诉我这不是问题。

lapply 最终使用 .Internal(lapply(X,FUN)) 最终在 C 源代码中调用 do_lapplyhttps://github.com/SurajGupta/r-source/blob/91aaa43312da6b0e6906ef221fd7756dc0459843/src/main/apply.c

我的猜测是,因为sapply 固有地将两个参数传递给SEXP args... 参数试图创建sapplySEXP argssapply(lst, "[", 之后的所有内容,并且因为它无法弄清楚在到达之前如何处理1,j= simplify=FALSE, USE.NAMES=FALSE,失败了。虽然这只是我的猜测。而lapply 没有将其他参数强制转换为SEXP args,因此它可以以不同的方式处理1,j=

这篇 Understanding how .Internal C functions are handled in R 的帖子很好地解释了一些 C 的细节。

希望这有助于在一定程度上解释这些差异,或者至少可以作为具有更高 R 开发技能的人的起点。

【讨论】:

    猜你喜欢
    • 2015-10-07
    • 2019-02-01
    • 1970-01-01
    • 2013-05-22
    • 2019-09-10
    • 2020-12-19
    • 2015-01-26
    • 2011-03-09
    • 1970-01-01
    相关资源
    最近更新 更多