R:应用/应用名称的不同行为

  • 本文关键字:应用 r
  • 更新时间 :
  • 英文 :


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

cc<-c("1","2")
ff<-function(x) { list(myname=x)}
aa<-unlist(lapply(cc,ff))
bb<-sapply(cc,ff)

我希望 aa 和 bb 是相同的,但是:

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

我知道使用。但是,要应用的 NAMES 参数 -

  1. 它被记录为 -

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

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

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

这是怎么回事?这可能是 R 问题吗?


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

unlist(lapply(cc,ff)

而是

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

(这是确切的内部取消列表调用(。

仔细看看这个:

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>