Dans R, comment obtenir le nom d'un objet après son envoi à une fonction?


136

Je cherche l'inverse de get().

Étant donné un nom d'objet, je souhaite que la chaîne de caractères représentant cet objet soit extraite directement de l'objet.

Exemple trivial avec le fait d' fooêtre l'espace réservé pour la fonction que je recherche.

z <- data.frame(x=1:10, y=1:10)

test <- function(a){
  mean.x <- mean(a$x)
  print(foo(a))
  return(mean.x)}

test(z)

Serait imprimer:

  "z"

Mon travail, qui est plus difficile à implémenter dans mon problème actuel, est:

test <- function(a="z"){
  mean.x <- mean(get(a)$x)
  print(a)
  return(mean.x)}

test("z")

35
Je pense que deparse(substitute(...))c'est ce que vous recherchez
Chase

2
Mauvais exemple cependant d'avoir la variable appelée "z" et le paramètre à tester également appelé "z" ... L'impression de "z" ne vous dit pas vraiment si vous l'avez fait correctement alors ;-)
Tommy

@Tommy, a essayé de l'améliorer, mais merci de l'améliorer si vous le souhaitez.
Etienne Low-Décarie

Le contraire de getdans R est, assignmais je ne suis pas sûr que ce soit ce que vous recherchez vraiment ...
Tom Kelly

Réponses:


161

Le vieux truc de deparse-substitut:

a<-data.frame(x=1:10,y=1:10)
test<-function(z){
   mean.x<-mean(z$x)
   nm <-deparse(substitute(z))
   print(nm)
   return(mean.x)}

 test(a)
#[1] "a"   ... this is the side-effect of the print() call
#          ... you could have done something useful with that character value
#[1] 5.5   ... this is the result of the function call

Edit: Ran it avec le nouvel objet de test

Remarque: cela ne réussira pas dans une fonction locale lorsqu'un ensemble d'éléments de liste est passé du premier argument à lapply(et cela échoue également lorsqu'un objet est passé d'une liste donnée à une forboucle.) Vous pourrez extraire le ".Names" -attribut et l'ordre de traitement à partir du résultat de la structure, s'il s'agissait d'un vecteur nommé en cours de traitement.

> lapply( list(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
$a
$a[[1]]
[1] "X"    ""     "1L]]"


$b
$b[[1]]
[1] "X"    ""     "2L]]"

> lapply( c(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
$a
$a[[1]]
[1] "structure(c(4, 5), .Names = c(\"a\", \"b\"))" ""                                            
[3] "1L]]"                                        


$b
$b[[1]]
[1] "structure(c(4, 5), .Names = c(\"a\", \"b\"))" ""                                            
[3] "2L]]"  

11
deparse(quote(var))

Ma compréhension intuitive dans laquelle la citation gèle la var ou l'expression de l'évaluation et la fonction deparse qui est l'inverse de la fonction d'analyse rend ce symbole figé à String


6

Notez que pour les méthodes d'impression, le comportement peut être différent.

print.foo=function(x){ print(deparse(substitute(x))) }
test = list(a=1, b=2)
class(test)="foo"
#this shows "test" as expected
print(test)

#this shows 
#"structure(list(a = 1, b = 2), .Names = c(\"a\", \"b\"), class = \"foo\")"
test

D'autres commentaires que j'ai vus sur les forums suggèrent que le dernier comportement est inévitable. Ceci est malheureux si vous écrivez des méthodes d'impression pour les packages.


Peut-être que cela devrait être: print.foo=function(x){ cat(deparse(substitute(x))) }ouprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
IRTFM

1
Ouprint.foo=function(x){ print.default(as.list(x)) }
IRTFM
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.