2016-09-14 4 views
0

Dans une fonction simple en utilisant ... pour fournir une liste d'arguments, est-il possible que la fonction de trouver les noms des objets passés de la appelant environnement? Si c'est le cas, comment?R: obtenir les noms des arguments passés dans `` ...

Cela se pose dans le contexte de la question, printing matrices and vectors side by side, mais est probablement plus général. Dans ce contexte, les arguments ... peuvent également inclure des chaînes de caractères, pour lesquelles aucun nom n'est requis. Voici mon MWE, où j'ai essayé d'utiliser deparse(substitute()), mais en vain.

test_names <- function(...) { 
    # get arguments 
    args <- list(...) 
    chars <- sapply(args, is.character) 
    names <- sapply(args, function(x) if(is.character(x)) " " else deparse(substitute(x))) 
    names 
} 

Test:

A = matrix(c(0.5, 1, 3, 0.75, 2.8, 4), nrow = 2) 
x = c(0.5, 3.7, 2.3) 
y = c(0.7, -1.2) 
b = A %*% x - y 

> test_names(A, " * ", x, " - ", y, " = ", b) 
[1] "X[[i]]" " "  "X[[i]]" " "  "X[[i]]" " "  "X[[i]]" 
> 

Ma sortie souhaitée pour ce serait le vecteur de caractères de longueur 7:

[1] "A" " " "x" " " "y" " " "b" 

Il est surprenant ici que les résultats sont tous X[[i]], quand il n'est pas X mentionné nulle part.

Après @ la réponse de Roland, cela semble faire ce que je veux:

test_names2 <- function(...) { 
    argnames <- sys.call() 
    unlist(lapply(argnames[-1], as.character)) 
} 

> test_names2(A, " * ", x, " - ", y, " = ", b) 
[1] "A" " * " "x" " - " "y" " = " "b" 
+0

Vous obtenez ceux de lapply. Il ne conserve pas les noms de liste. – Roland

+0

Modifié pour afficher la sortie souhaitée – user101089

Répondre

1

Utilisation sys.call:

test_names <- function(...) { 
    argnames <- sys.call() 
    paste(lapply(argnames[-1], as.character), collapse = "") 
} 
#[1] "A * x - y = b" 
0

Comme la liste de courrier électronique décrit (here) soit sys.call comme Roland dit ou match.call peut être utilisé pour cela.

Par rapport à la solution de Roland, une solution avec match.call ressemble

f = function(...){ 
    return(match.call()) 
} 

d = f(x = 1, b = 5) 
d 
#f(x = 1, b = 5) 
as.list(d[-1]) 
#$x 
#[1] 1 
# 
#$b 
#[1] 5 

Il faut donc utiliser ce peu comme ça, parce que le premier élément est le nom de la fonction elle-même.

f = function(...){ 
    return(as.list(match.call())[-1]) 
} 

Ils sont similaires, mais le help page dit:

sys.call() est similaire [à match.call()], mais ne se développe pas l'argument des noms;

Voici donc une différence.