【问题标题】:Why does sapply() return a list?为什么 sapply() 返回一个列表?
【发布时间】:2012-03-12 14:00:45
【问题描述】:

我在R 中使用sapply() 函数遇到了一个奇怪的行为。这个函数应该返回一个向量,但在给它一个空向量的特殊情况下,它会返回一个列表。

使用向量的正确行为:

a = c("A", "B", "C")
a[a == "B"]  # Returns "B"
a[sapply(a, function(x) {x == "B"})] # Returns "B"

使用 NULL 值的正确行为:

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

为什么?是bug吗?

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

【问题讨论】:

  • Protip-它从来都不是错误
  • @ChrisBeeley - 从来不是一个错误,总是一个“功能”;-) R(和 S)有一堆不太理想的“功能”,这就是其中之一。 1:0 是另一个...

标签: r


【解决方案1】:

真正的原因是sapply 不知道你的函数不调用它会返回什么。在您的情况下,该函数返回一个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()

请参阅?vapply 了解更多信息。

【讨论】:

    【解决方案2】:

    函数?sapply的帮助在Value部分有这个

    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() 完全无关。在这两种情况下,它都会返回一致的输出,即一个空列表。

    【讨论】:

      【解决方案3】:

      实际上,它们都返回list。两者之间的唯一区别是,当您尝试索引 NULL 时,它总是返回 NULL(即使您的索引是一个列表),但是当您尝试索引一个空向量时,它会检查索引,并意识到它是一个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!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-01-05
        • 2016-09-18
        • 1970-01-01
        • 2019-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多