为什么sapply()会返回一个列表?

Bix*_*Bix 15 r

我在R中遇到了一个带有该sapply()功能的奇怪行为.该函数应该返回一个向量,但在给它一个空向量的特殊情况下,它返回一个列表.

使用向量纠正行为:

a = c("A", "B", "C")
a[a == "B"]  # Returns "B"
a[sapply(a, function(x) {x == "B"})] # Returns "B"
Run Code Online (Sandbox Code Playgroud)

使用NULL值更正行为:

a = NULL
a[a == "B"]  # Returns NULL
a[sapply(a, function(x) {x == "B"})] # Returns NULL
Run Code Online (Sandbox Code Playgroud)

使用空向量的奇怪行为:

a = vector()
a[a == "B"]  # Returns NULL
a[sapply(a, function(x) {x == "B"})] # Erreur : type 'list' d'indice incorrect
Run Code Online (Sandbox Code Playgroud)

与此语句相同的错误消息:

a[list()] # Erreur dans a[list()] : type 'list' d'indice incorrect
Run Code Online (Sandbox Code Playgroud)

为什么?这是一个错误吗?

由于这种奇怪的行为,我使用unlist(lapply()).

Tom*_*mmy 19

真正的原因是sapply不知道你的函数在没有调用的情况下会返回什么.在你的情况下,函数返回a logical,但由于sapply给出了一个空列表,因此永远不会调用该函数.因此,它必须提出一个类型,它默认为list.

......出于这个原因(以及性能),我们vapply推出了!它要求您指定返回值类型(和长度).这使它能够做正确的事情.作为奖励,它也更快!

sapply(LETTERS[1:3], function(x) {x == "B"}) # F, T, F
sapply(LETTERS[0], function(x) {x == "B"})   # list()

vapply(LETTERS[1:3], function(x) {x == "B"}, logical(1)) # F, T, F
vapply(LETTERS[0], function(x) {x == "B"}, logical(1))   # logical()
Run Code Online (Sandbox Code Playgroud)

有关详情?vapply,请参阅.


Rei*_*son 6

函数的帮助?sapplyValue部分中有这个

For ‘sapply(simplify = TRUE)’ and ‘replicate(simplify = TRUE)’: if
‘X’ has length zero or ‘n = 0’, an empty list.
Run Code Online (Sandbox Code Playgroud)

在你的两种情况下:

> length(NULL)
[1] 0
> length(vector())
[1] 0
Run Code Online (Sandbox Code Playgroud)

因此sapply()回报:

> sapply(vector(), function(x) {x == "B"})
list()
> sapply(NULL, function(x) {x == "B"})
list()
Run Code Online (Sandbox Code Playgroud)

您的错误不是来自,sapply()而是来自[如下所示:

> a[list()]
Error in a[list()] : invalid subscript type 'list'
Run Code Online (Sandbox Code Playgroud)

因此,问题与如何执行子NULL向量和空向量(vector())有关.完全没什么关系sapply().在这两种情况下,它都返回一致的输出,一个空列表.