R 为什么sapply()返回一个列表?
我在使用R 为什么sapply()返回一个列表?,r,R,我在使用sapply()函数时遇到了一个奇怪的行为。这个函数应该返回一个向量,但在特殊情况下,如果给它一个空向量,它将返回一个列表 向量的正确行为: a = c("A", "B", "C") a[a == "B"] # Returns "B" a[sapply(a, function(x) {x == "B"})] # Returns "B" 使用空值时的正确行为: a = NULL a[a == "B"] # Returns NULL a[sapply(a, function(x) {x
sapply()
函数时遇到了一个奇怪的行为。这个函数应该返回一个向量,但在特殊情况下,如果给它一个空向量,它将返回一个列表
向量的正确行为:
a = c("A", "B", "C")
a[a == "B"] # Returns "B"
a[sapply(a, function(x) {x == "B"})] # Returns "B"
使用空值时的正确行为:
a = NULL
a[a == "B"] # Returns NULL
a[sapply(a, function(x) {x == "B"})] # Returns NULL
空向量的奇怪行为:
a = vector()
a[a == "B"] # Returns NULL
a[sapply(a, function(x) {x == "B"})] # Erreur : type 'list' d'indice incorrect
与此语句相同的错误消息:
a[list()] # Erreur dans a[list()] : type 'list' d'indice incorrect
为什么??是虫子吗
由于这种奇怪的行为,我使用了
unlist(lappy())
实际上,它们都返回一个列表。两者之间唯一的区别是,当您尝试索引NULL
时,它总是返回NULL(即使您的索引是一个列表),但当您尝试索引一个空向量时,它会检查索引,并意识到它是一个列表
a = NULL
res = sapply(a, function(x) x == "B") # Res is an empty list
a[res] # returns NULL, because any index of NULL is NULL.
a = vector()
res = sapply(a, function(x) x == "B") # Still an empty list.
a[res] # but you can't index a vector with a list!
函数?sapply
的帮助在值中有此项
For ‘sapply(simplify = TRUE)’ and ‘replicate(simplify = TRUE)’: if
‘X’ has length zero or ‘n = 0’, an empty list.
在这两种情况下:
> length(NULL)
[1] 0
> length(vector())
[1] 0
因此sapply()
返回:
> sapply(vector(), function(x) {x == "B"})
list()
> sapply(NULL, function(x) {x == "B"})
list()
您的错误不是来自sapply()
,而是来自[
,如下所示:
> a[list()]
Error in a[list()] : invalid subscript type 'list'
因此,问题与如何执行NULL
和空向量(vector()
)的子集设置有关。与sapply()无关
。在这两种情况下,它都返回一致的输出,一个空列表。造成这种情况的真正原因是sapply
不调用它就不知道函数将返回什么。在您的情况下,函数返回一个逻辑的,但由于sapply
被提供了一个空列表,因此函数永远不会被调用。因此,它必须提供一个类型,默认为list
a = NULL
res = sapply(a, function(x) x == "B") # Res is an empty list
a[res] # returns NULL, because any index of NULL is NULL.
a = vector()
res = sapply(a, function(x) x == "B") # Still an empty list.
a[res] # but you can't index a vector with a 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()
有关更多信息,请参见?vapply
。Protip-它从来都不是bug@ChrisBeeley-从来都不是bug,总是一个“特性”;-不过R(和S)有一堆不太理想的“特性”,这就是其中之一。1:0
是另一个。。。