2010-12-21 49 views
14

我想知道如何可以從R中一個列表對象遍歷一個密鑰/值對,如下面的例子:遍歷從列表()鍵/值對

toto <- list(a="my name is",b="I'm called",c="name:") 
myfun <- function(key,value) paste(value,key) 
for(key in names(toto)) toto[key] <- myfun(key,toto[[key]]) 

是有一種方法可以避免for循環(使用lapply()等)。會更快嗎?

謝謝!

+2

只要記住,`lapply`仍然涉及迭代,而它很可能比'for'快一點,但情況並非總是如此(它肯定不等於向量化函數)。 http://stackoverflow.com/questions/2275896/is-rs-apply-family-more-than-syntactic-sugar/2276001#2276001 – Shane 2010-12-21 14:27:11

回答

12

所有的最好的解決辦法是簡單地調用paste的情況下直接循環(它已經向量化):

> paste(toto, names(toto)) 
[1] "my name is a" "I'm called b" "name: c" 

類似的問題previously asked on R-Help,有幾個創意解決方案。 lapply無法在功能中顯示名稱。由托馬斯·拉姆利基於該功能是由羅曼·弗朗索瓦提供的東西:

yapply <- function(X,FUN, ...) { 
    index <- seq(length.out=length(X)) 
    namesX <- names(X) 
    if(is.null(namesX)) 
    namesX <- rep(NA,length(X)) 

    FUN <- match.fun(FUN) 
    fnames <- names(formals(FUN)) 
    if(! "INDEX" %in% fnames){ 
    formals(FUN) <- append(formals(FUN), alist(INDEX=)) 
    } 
    if(! "NAMES" %in% fnames){ 
    formals(FUN) <- append(formals(FUN), alist(NAMES=)) 
    } 
    mapply(FUN,X,INDEX=index, NAMES=namesX,MoreArgs=list(...)) 
} 

下面是使用的例子:

> yapply(toto, function(x) paste(x, NAMES)) 
      a    b    c 
"my name is a" "I'm called b"  "name: c" 
+8

「mapply」在OP案例中的基本用法是`mapply(myfun,key = names(toto),value = toto)`。 – Marek 2010-12-21 14:37:46

6

這應該爲你做它:

do.call(paste, list(toto, names(toto))) 
+4

沒有必要在這裏做。粘貼(託託,名稱(託託))的作品一樣好。而且在我眼中更加優雅。 – 2010-12-21 14:33:05