簡體   English   中英

R:sapply / lapply 名稱不同的行為

[英]R: sapply / lapply Different Behaviour with Names

我將一些問題減少到以下玩具代碼:

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"

我知道 USE.NAMES sapply 的參數,但是 -

  1. 它被記錄為 -

USE.NAMES 邏輯; 如果 TRUE 並且 X 是字符,則使用 X 作為結果的名稱,除非它已經有名稱

所以在這種情況下應該沒有影響,

  1. 在內部,它甚至沒有傳遞給 simple2array,因此也沒有傳遞給最終的 unlist。

這里發生了什么? 這可能是 R 問題嗎?


編輯:經過進一步調查,結果發現差異的根本原因是 sapply 本質上等同於不

unlist(lapply(cc,ff)

而是

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

(這是確切的內部 unlist 調用)。

仔細看看這個:

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

lapply 的lapply本身沒有名字。 看:

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

lapply的lapply其實是一個無名列表 a 的每個元素都是a命名列表

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

所以實際上, USE.NAMES將適用, sapply將分配cc的內容作為 lapply 的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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM