W R, jak uzyskać nazwę obiektu po wysłaniu go do funkcji?


139

Szukam odwrotności get().

Biorąc pod uwagę nazwę obiektu, chciałbym, aby ciąg znaków reprezentujący ten obiekt został wyodrębniony bezpośrednio z obiektu.

Trywialny przykład z foobyciem symbolem zastępczym funkcji, której szukam.

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)

Wydrukowałoby:

  "z"

Moje obejście, które jest trudniejsze do wdrożenia w moim obecnym problemie, to:

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

test("z")

35
Myślę, że deparse(substitute(...))właśnie tego szukasz
Chase

2
Zły przykład, że zmienna o nazwie "z" i parametr do przetestowania również nazywany "z" ... Wydrukowanie "z" tak naprawdę nie mówi ci, czy zrobiłeś to poprawnie ;-)
Tommy

@Tommy, próbował go ulepszyć, ale jeśli chcesz, popraw go, edytując.
Etienne Low-Décarie

Przeciwieństwem getw R jest, assignale nie jestem pewien, czego naprawdę szukasz ...
Tom Kelly,

Odpowiedzi:


163

Stara sztuczka polegająca na zastępowaniu rzeczy:

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

Edycja: uruchomiono go z nowym obiektem testowym

Uwaga: nie powiedzie się to wewnątrz funkcji lokalnej, gdy zestaw elementów listy zostanie przekazany z pierwszego argumentu do lapply(a także nie powiedzie się, gdy obiekt jest przekazywany z listy podanej do for-loop). ".Names" -attribute i kolejność przetwarzania na podstawie wyniku struktury, jeśli przetwarzany był nazwany wektor.

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

13
deparse(quote(var))

Moje intuicyjne zrozumienie W którym cudzysłów zamraża zmienną lub wyrażenie z wartościowania, a funkcja deparse, która jest odwrotnością funkcji parsowania, powoduje, że zamrożony symbol z powrotem na String


6

Zauważ, że w przypadku metod drukowania zachowanie może być inne.

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 (just typing 'test' on the R command line)
test
#shows
#"structure(list(a = 1, b = 2), .Names = c(\"a\", \"b\"), class = \"foo\")"

Inne komentarze, które widziałem na forach, sugerują, że ostatnie zachowanie jest nieuniknione. Jest to niefortunne, jeśli piszesz metody wypisywania pakietów.


Być może powinno to być: print.foo=function(x){ cat(deparse(substitute(x))) }lubprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
IRTFM

1
Lubprint.foo=function(x){ print.default(as.list(x)) }
IRTFM

as.list()nie zadziała, ponieważ „test” może oznaczać cokolwiek. Właśnie użyłem listy w moim przykładzie zabawki.
Eli Holmes

Aktualizacja R 3.6. Obecnie następuje niewielka zmiana w zachowaniu, ale nadal nie została ona naprawiona. print(test)produkuje testpodczas gdy testw wierszu poleceń produkuje x(nie test, jak chcesz). Wszystkie mają takie samo zachowanie. print.foo=function(x){ print(deparse(substitute(x))) }lub print.foo=function(x){ cat(deparse(substitute(x))) }lubprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
Eli Holmes
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.