해당 함수 내에서 함수 이름 결정


15

익명이 아닌 함수 내에서 함수 이름을 얻으려면 어떻게해야합니까? 아래에서는이 작업을 수행하는 함수 또는 프로세스 magical_r_function()가 있고 예상 출력이 무엇인지 가정 합니다.

my_fun <- function(){
      magical_r_function()
}
my_fun()
## [1] "my_fun"


foo_bar <- function(){
      magical_r_function()
}
foo_bar()
## [1] "foo_bar"

ballyhoo <- function(){
    foo_bar()
}
ballyhoo()
## [1] "foo_bar"

tom_foolery <- foo_bar
tom_foolery()
## [1] "tom_foolery"

답변:


18
as.character(match.call()[[1]])

데모:

my_fun <- function(){
  as.character(match.call()[[1]])
}
my_fun()
# [1] "my_fun"
foo_bar <- function(){
  as.character(match.call()[[1]])
}
foo_bar()
# [1] "foo_bar"
ballyhoo <- function(){
  foo_bar()
}
ballyhoo()
# [1] "foo_bar"
tom_foolery <- foo_bar
tom_foolery()
# [1] "tom_foolery"

타일러, 나는 확실히 신경 쓰지 않고 (GG도 좋습니다), 어떤 대답을 선택할 기준이 되었습니까?
— r2evans

좋은 질문. 두 가지 모두 탁월한 선택입니다. 둘 다 내 테스트에서 동일하게 작동하는 것 같습니다. GG는 좀 더 자세히 설명했습니다. 결정하기가 힘들었습니다.
— Tyler Rinker

새로운 이름에 기능을 할당하는 마지막 조건을 면밀히 조사하면 원래 요청과 더 밀접하게 일치합니다.
— Tyler Rinker

내 의견만으로 변경하지 마십시오! 나는 깨지 않고 담당자를 필요로하지 않습니다 (그러나 모두가 나보다 조금 더 있습니다). 아뇨, 그냥 궁금 했어요 난 둘 생각 match.call과 sys.call"효과"와 "요구 사항"에 약간의 차이가 유효한 기본 기능입니다. 그래서 나는 당신이 다른 것을 선호하는 통찰력이 궁금합니다.
— r2evans

12

시도 sys.call(0)호출 객체 출력이 그냥 문자열로 이름을 원한다면 것을 확인 또는 deparse 경우. 다음은이 테스트에 대한 몇 가지 테스트입니다. sys.call은 이름과 인수를 모두 반환하며 [[1]]은 이름 만 선택합니다.

my_fun <- function() deparse(sys.call(0)[[1]])

g <- function() my_fun()

my_fun()
## [1] "my_fun"

g()
## [1] "my_fun"

기능 이름

함수에는 실제로 이름이 없습니다. 함수 이름으로 간주하는 것은 실제로 함수를 보유하고 함수 자체의 일부가 아닌 변수입니다. 함수는 인수, 본문 및 환경으로 구성됩니다. 이러한 구성 요소에는 함수 이름이 없습니다.

익명 함수

또한 익명의 기능을 가질 수 있으며 위와 함께 사용하면 이상한 결과를 반환 할 수 있습니다.

sapply(1:3, function(x) deparse(sys.call(0)[[1]]))
## [1] "FUN" "FUN" "FUN"

가장자리 케이스

특히 익명 함수와 관련하여 deparse여러 요소를 반환 하는 일부 상황이 있으므로 이러한 에지 사례를 다루려면 nlines = 1 인수를 사용하여 deparse (...) [[1]] 또는 R 4.0.0에서 deparse1을 사용하여 @Konrad Rudolph가 언급했습니다.

Map(function(x) deparse(sys.call(0)[[1]], nlines = 1), 1:2)
## [[1]]
## [1] "function (x) "
## 
## [[2]]
## [1] "function (x) "

Map(function(x) deparse(sys.call(0)[[1]]), 1:2)  # without nlines=1
## [[1]]
## [1] "function (x) "             "deparse(sys.call(0)[[1]])"
##
## [[2]]
## [1] "function (x) "             "deparse(sys.call(0)[[1]])"

다른

기억하십시오 . 함수 이름을 원하는 이유가 재귀 적으로 함수를 호출하는 것이라면 Recall()대신 사용하십시오. 도움말 파일에서 :

fib <- function(n)
   if(n<=2) { if(n>=0) 1 else 0 } else Recall(n-1) + Recall(n-2)
fib(4)
## [1] 3

warning and stop 이들은 둘 다 전달 된 인수와 함께 함수 이름을 발행하므로 현재 함수 이름을 얻을 필요가 없습니다.

testWarning <- function() warning("X")
testWarning()
## Warning message:
## In testWarning() : X

2
deparse1기능 의 도입을 통해 R 4.0에서“가장자리 케이스”가 우아하게 해결되었습니다 . deparse채택이 충분히 높아지면 기본적으로 대신 사용을 시작해야한다고 생각합니다 .
— Konrad Rudolph

에 대한 +1 Recall, OP가 실제로 필요한 것입니다. 그러나, 피보나치 시퀀스의 당신의 예는 정말 좋은 하나되지 않습니다 : 그것은 당신이 자주 전화를 반복하는 문제가 있습니다 위해 fib(10), fib(8)(한 번, 총 두 번 호출을 fib(10)직접 한 번 fib(9)), fib(7)3 번 호출, fib(6)호출 5 회. 어디로 가는지 봅니까?
— Emil Bode

@Emil, 이것은 Recall 도움말 페이지 (답변에 명시된 바와 같이)에서 바로 요점을 분명히 보여줍니다. 다른 이유로 마음에 들지 않으면 R 개발자에게 불만을 제기 할 수 있습니다.
— G. Grothendieck

5

우리는 또한 사용할 수 있습니다

my_fun <- function(){
  as.character(as.list(sys.calls()[[1]])[[1]])
 }

my_fun()
#[1] "my_fun"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.