2010-12-21 17 views
14

me gustaría saber cómo puedo repetir un par clave/valor de un objeto de lista en I, como el siguiente ejemplo:iterar sobre par clave/valor de una lista()

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]]) 

Es hay una manera de evitar el bucle for (usando lapply() o similar). ¿Sería más rápido?

Gracias!

+2

Hemos de tener en cuenta que 'lapply' todavía implica iteración, y si bien es probable un poco más rápido que 'for', este no es siempre el caso (y ciertamente no es equivalente a vectorizar la función). http://stackoverflow.com/questions/2275896/is-rs-apply-family-more-than-syntactic-sugar/2276001#2276001 – Shane

Respuesta

12

La mejor solución de todos es simplemente llamar paste directamente sin necesidad de un bucle (se vectorizado ya):

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

Una pregunta similar previously asked on R-Help, con varias soluciones creativas. lapply no se pueden mostrar los nombres dentro de la función. Esta función fue proporcionado por Romain Francois basado en algo por Thomas Lumley:

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(...)) 
} 

Aquí hay un ejemplo de uso:

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

Y el uso básico de 'mapply' para el caso OP será' mapply (myfun, key = names (toto), value = toto) '. – Marek

+1

@Marek ¡Buen punto! Pensé que valía la pena cubrir algo más que simplemente pegar en caso de que el OP tuviera otros usos en mente con la pregunta. También me gustaría señalar que esto es básicamente lo que 'yapply' hace detrás de las escenas (vea la última línea de esa función). – Shane

+1

preferiría 'mapply' cualquier día para' aplicar ya' para que cualquier programador decente de R pueda entender fácilmente lo que está haciendo, ya que es una función de aplicación "estándar" de todos modos. –

6

Esto debe hacerlo por usted:

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

no hay necesidad de hacer llamadas aquí. pegar (toto, nombres (toto)) funciona igual de bien. Y es en mis ojos aún más elegante. –