Як у R, як отримати ім'я об'єкта після його надсилання до функції?


135

Я шукаю реверс get().

Враховуючи ім'я об'єкта, я хочу, щоб рядок символів, що представляє цей об'єкт, був вилучений безпосередньо з об'єкта.

Тривіальний приклад, fooякий є заповнювачем функції, яку я шукаю.

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)

Буде надруковано:

  "z"

Моя робота, яку важче реалізувати в моїй нинішній проблемі:

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

test("z")

35
Я думаю, deparse(substitute(...))це те, що ти шукаєш
Чейз

2
Поганий приклад, хоча мати змінну під назвою "z", а параметр для тестування також називати "z" ... Друк "z" насправді не говорить вам, чи правильно ви це зробили тоді ;-)
Томмі

@Tommy, спробував її покращити, але, будь-ласка, вдосконаліть її за допомогою редагування.
Етьєн Лоу-Декарі

Протилежністю getв R є, assignале я не впевнений, що ви насправді шукаєте ...
Том Келлі,

Відповіді:


160

Старий трюк із заміною замінника:

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

Редагувати: розмістити його за допомогою нового тестового об’єкта

Примітка: це не вдасться всередині локальної функції, коли набір елементів списку буде передано з першого аргументу в lapply(і він також не вдається, коли об'єкт передається зі списку, наданого в for-loop.) Ви зможете витягнути ".Names" - розподіл і порядок обробки з структури отримують, якби це був названий вектор, який оброблявся.

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

Моє інтуїтивне розуміння, в якому цитата заморожує вар або вираз з оцінювання, а функція deparse, яка є зворотною функцією розбору, робить цей заморожений символ назад до String


6

Зауважте, що для методів друку поведінка може бути різною.

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

Інші коментарі, які я бачив на форумах, свідчать про те, що остання поведінка неминуча. Це прикро, якщо ви пишете методи друку для пакетів.


Можливо, це має бути: print.foo=function(x){ cat(deparse(substitute(x))) }абоprint.foo=function(x){ print(deparse(substitute(x)), quote=FALSE) }
IRTFM

1
Абоprint.foo=function(x){ print.default(as.list(x)) }
IRTFM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.