उस फ़ंक्शन के भीतर फ़ंक्शन का नाम निर्धारित करें


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"

टायलर, मैं निश्चित रूप से बुरा नहीं मानता (और जीजी अच्छा है, भी), लेकिन आपके मानदंड क्या थे जिनके लिए उत्तर चुनना है?
r2evans

अच्छा प्रश्न। दोनों उत्कृष्ट विकल्प। दोनों मेरे परीक्षणों में समान काम करते दिख रहे थे। जीजी ने थोड़ा और विस्तार प्रदान किया है। यह तय करना कठिन था।
टायलर रिंकर

किसी फ़ंक्शन को एक नए नाम पर असाइन करने की अंतिम स्थिति का बारीकी से निरीक्षण करने पर, यह एक और अधिक बारीकी से मूल पूछ के साथ संरेखित करता है।
टायलर रिंकर

कृपया मेरी टिप्पणी पर पूरी तरह से मत बदलो! मैं लहराता नहीं हूं और रेप्स की जरूरत है (हालांकि y'all मेरे पास थोड़ा ज्यादा है)। नहीं, मैं बस उत्सुक था। मैं दोनों लगता है match.callऔर sys.call"प्रभाव" और "आवश्यकताओं" में थोड़ा अंतर के साथ वैध आधार कार्य कर रहे हैं। इसलिए मैं अंतर्दृष्टि के लिए उत्सुक था आप एक दूसरे पर पसंद करने में हो सकता है।
r2evans

12

कोशिश करें sys.call(0)कि कॉल ऑब्जेक्ट आउटपुट ठीक है या फिर डिले करें कि यदि आप केवल एक वर्ण स्ट्रिंग के रूप में नाम चाहते हैं। नीचे इस के कुछ परीक्षण दिए गए हैं। 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 तर्क का उपयोग करें या अवमूल्यन (...) [[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

चेतावनी और रोकना ये दोनों फ़ंक्शन का नाम जारी करते हैं, साथ ही जो भी तर्क उनके पास जाता है, इसलिए वर्तमान फ़ंक्शन नाम प्राप्त करने की कोई आवश्यकता नहीं है।

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

2
आपका "बढ़त मामला" deparse1फ़ंक्शन की शुरूआत के माध्यम से आर 4.0 में सुरुचिपूर्ण ढंग से हल किया गया है। मैं अनुमान लगा रहा हूं कि हमें deparseडिफ़ॉल्ट रूप से उपयोग करना शुरू करना चाहिए , एक बार गोद लेने की क्षमता काफी अधिक है।
कोनराड रुडोल्फ

+1 Recall, जिसके लिए मुझे लगता है कि ओपी को वास्तव में जरूरत थी। हालांकि, फिबोनाची अनुक्रम का आपका उदाहरण वास्तव में अच्छा नहीं है: इसमें यह समस्या है कि आप अक्सर कॉल दोहराते हैं: के लिए fib(10), fib(8)कुल में 2 बार ( fib(10)सीधे एक बार, एक बार fib(9)) fib(7)कहा जाता है, 3 बार fib(6)कहा जाता है 5 बार। देखें यह कहाँ जा रहा है?
एमिल बोड

@ ईमिल, यह रिकॉल सहायता पृष्ठ (जैसा कि उत्तर में कहा गया है) से सही है, इसलिए यह निश्चित रूप से इस बिंदु को दिखाता है। यदि आप इसे अन्य आधारों पर पसंद नहीं करते हैं, तो आप आर डेवलपर्स से शिकायत कर सकते हैं।
जी। ग्रेंडेंडिक

5

हम भी उपयोग कर सकते हैं

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

my_fun()
#[1] "my_fun"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.