【问题标题】:R: sapply / lapply Different Behaviour with NamesR: sapply / lapply 名称的不同行为
【发布时间】:2020-10-14 21:56:30
【问题描述】:

我将一些问题简化为以下玩具代码:

cc<-c("1","2")
ff<-function(x) { list(myname=x)}

aa<-unlist(lapply(cc,ff))
bb<-sapply(cc,ff)

I'd expect aa 和 bb 相同,但是:

> aa
myname myname 
   "1"    "2" 
> bb
$`1.myname`
[1] "1"

$`2.myname`
[1] "2"

不过,我知道 USE.NAMES 参数是 sapply -

  1. documented 为 -

USE.NAMES 逻辑;如果 TRUE 并且 X 是字符,则使用 X 作为名称 结果除非它已经有名字

所以在这种情况下应该没有影响,

  1. 在内部,它甚至没有传递给 simple2array,因此也没有传递给最终的 unlist。

这里发生了什么?这可能是 R 问题吗?


编辑:经过进一步调查,结果发现差异的根本原因是 sapply 基本上等同于不

unlist(lapply(cc,ff)

而是为了

unlist(lapply(cc, ff), recursive = FALSE)

(这是确切的内部 unlist 调用)。

【问题讨论】:

  • cc 没有名称,因此添加了它们
  • @user20650 ff 添加名称。
  • 我把“除非它有名字”中的 it 当作 X 输入而不是结果,但是在重新阅读时我可能会弄错
  • ...(就像这里发生的事情names(cc) = c("A", "B"); sapply(cc,ff)

标签: r


【解决方案1】:

仔细看这个:

lapply(cc, ff)
#> [[1]]
#> [[1]]$myname
#> [1] "1"
#>
#>
#> [[2]]
#> [[2]]$myname
#> [1] "2"

lapply 的输出本身没有名称。看:

a <- lapply(cc, ff)
names(a)
#> NULL

lapply 的输出实际上是一个未命名列表a 的每个元素都是一个命名列表

names(a[[1]])
#> [1] "myname"
names(a[[2]])
#> [1] "myname"

所以事实上,USE.NAMES 将适用,sapply 将分配cc 的内容作为lapply 输出的名称,其中sapply 是一个瘦包装器,如文档中所述。遵循代码非常简单:

sapply
#> function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE) 
#> {
#>     FUN <- match.fun(FUN)
#>     answer <- lapply(X = X, FUN = FUN, ...)
#>     if (USE.NAMES && is.character(X) && is.null(names(answer))) 
#>         names(answer) <- X
#>     if (!isFALSE(simplify) && length(answer)) 
#>         simplify2array(answer, higher = (simplify == "array"))
#>     else answer
#> }
#> <bytecode: 0x036ae7a8>
#> <environment: namespace:base>

【讨论】:

  • 谢谢,但请注意,以某种方式 连接 预先存在的名称和抄送的内容。我不确定这是否是预期的行为。
  • @OfekShilon 它预期的行为。它将名称连接起来,因为一旦将名称添加到顶级列表中,它就会将嵌套列表简化为单个层。当它这样做时,它会连接第一层和第二层的名称。试试unlist(list(a = list(b = 1), c = list(d = 1))) 看看我的意思
  • 啊,谢谢。为什么 class() 有区别? simple2array 本质上是一个 unlist 的包装器。
  • 我接受答案,但请注意我添加到问题中的其他信息。
  • @OfekShilon 谢谢你,也感谢你提供额外的信息。
猜你喜欢
  • 2013-10-31
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多