2011-02-18 19 views
10

dentro de una función defino un montón de variables escalares como esto:R: crear un vector llamado a partir de variables

a <- 10 
b <- a*100 
c <- a + b 

Al final de la función, que quieren volver a,b,c en un llamado vector de, con los mismos nombres que las variables, con la codificación mínima, es decir, que no quieren hacer:

c(a = a, b = b, c = c) 

¿hay una construcción del lenguaje que hace esto? Por ejemplo, si simplemente hago return(c(a,b,c)), devuelve un vector sin nombre, que no es lo que quiero. Actualmente tengo una manera de hacer esto hacky:

> cbind(a,b,c)[1,] 
    a b c 
    10 1000 1010 

¿Existe tal vez un mejor, menos hacky, así?

+1

¿Qué podría ser menos mínimo que c (a = a, b = b, c = c)? Tienes que especificar los nombres y valores en algún lugar. ¿O quieres que se dé cuenta mágicamente de que 'a' se llama 'a'? – Spacedman

+1

Sí, eso es lo que quiero, p. Ej. el 'cbind' de arriba hace eso, y estoy bastante contento con su minimality, pero me pregunté si había una manera más directa. Los nombres de las variables pueden ser largos ... y quiero ahorrar al escribir :) –

+0

que desea guardar al tipear, pero oculta su código (si veo una construcción así, lo saco del código lo antes posible) y pierde bastante rendimiento cuando se trata de vectores grandes y/o muchos. Realmente pensaría de nuevo si no estás encontrando una solución a algo que pueda ser resuelto de una manera diferente. –

Respuesta

11

Aquí hay una función para hacer eso, que también le permite nombrar opcionalmente algunos de los valores. No hay mucho que hacer, excepto el truco para obtener la expresión no evaluada y deparse en un único vector de caracteres.

c2 <- function(...) { 
    vals <- c(...) 

    if (is.null(names(vals))) { 
    missing_names <- rep(TRUE, length(vals)) 
    } else { 
    missing_names <- names(vals) == "" 
    } 
    if (any(missing_names)) { 
    names <- vapply(substitute(list(...))[-1], deparse, character(1)) 
    names(vals)[missing_names] <- names[missing_names] 
    } 

    vals 
} 

a <- 1 
b <- 2 
c <- 3 

c2(a, b, d = c) 
# a b d 
# 1 2 3 

en cuenta que no está garantizado para producir nombres sintácticamente válidos. Si lo desea, aplique la función make.names al vector names.

c2(mean(a,b,c)) 
# mean(a, b, c) 
#   1 

También, como con cualquier función que utiliza sustituto, c2 es más adecuado para el uso interactivo de ser utilizado dentro de otra función.

+0

@hadley: 'sustituto (list (...)) [- 1]' se puede abreviar con 'substitute (...())' – Tommy

+0

Acortado, pero confunde aún más. (Me doy cuenta de que la lista no se usa, pero transmite la intención) – hadley

+1

@hadley: He agregado dos funciones 'nc' y' nlist' a [mi paquete 'kimisc'] (https://github.com/krlmlr/ kimisc), acreditándote a ti y a esta respuesta. – krlmlr

Cuestiones relacionadas