2014-04-23 8 views
5

मैं आर expression ऑब्जेक्ट को समझने की कोशिश कर रहा हूं, लेकिन कुछ कठिनाइयों का सामना करना पड़ा।अभिव्यक्ति में यह आर कॉल ऑब्जेक्ट का मूल्यांकन क्यों नहीं किया जा सकता है? (कॉल ऑब्जेक्ट से निकालने वाला सबसेटिंग)

कोड स्निपेट:

a = 1 
b = 2 
x = expression(sin(a+b+1)) 
print(class(x[[1]][2])) 
eval(x[[1]][2]) 

परिणाम:

#//////////////////////////////////////////////////// 
x = expression(sin(a+b+1)) 
#//////////////////////////////////////////////////// 
print(class(x[[1]][2])) 
[1] "call" 
#//////////////////////////////////////////////////// 
x = expression(sin(a+b+1)) 
#//////////////////////////////////////////////////// 
print(class(x[[1]][2])) 
[1] "call" 
#//////////////////////////////////////////////////// 
eval(x[[1]][2]) 
Error in eval(expr, envir, enclos) : attempt to apply non-function 
2: eval(expr, envir, enclos) 
1: eval(x[[1]][2]) 

x[[1]][2] एक call वस्तु है, लेकिन क्यों यह मूल्यांकन नहीं किया जा सकता है?

उत्तर

11

आपको [[ ऑपरेटर का उपयोग करना चाहिए, न कि [

a <- 1 
b <- 2 
eval(x[[1]][[2]]) 
## [1] 4 

इसका कारण यह है कि आप (2 तत्व के अंदर देखो, और 2 तत्व से मिलकर किसी परिणाम को वापस नहीं) भाषा वस्तु से जानकारी निकालने के लिए करना चाहते हैं, और यह सबसेट तक नहीं।

दूसरे शब्दों में, एक call subsetting आप देता है एक call:

x[[1]][2] 
## (a + b + 1)() 

और a+b+1 जैसी कोई समारोह है, क्योंकि (वास्तव में, a+b+1 के मूल्यांकन का परिणाम एक समारोह वस्तु नहीं है), आर एक त्रुटि फेंकता है।

दिलचस्प है, अगर + एक समारोह वस्तु वापसी होगी, इस अर्थ बना सकता है:

:

"+" <- function(a, b) { function() print(":-)") } 
(a+b+1)() 
[1] ":-)" 

दूसरी ओर, एक फोन वस्तु से एक तत्व निकालने आप एक अभिव्यक्ति है कि मूल्यांकन किया जा सकता देता है

x[[1]][[2]] 
a + b + 1 

(btw, इस अभिव्यक्ति भी एक फोन, यहाँ "+"(a, "+"(b, 1)) के बराबर है।

संपादित करें

(f, a1, ..., an), 

जो हम आम तौर पर पढ़ते हैं:

f(a1, ..., an). 

इस प्रकार, अनुक्रम के पहले तत्व को बदलने के लिए प्रयोग किया जाता है एक वस्तु है अधिक औपचारिक रूप से, एक कॉल प्रपत्र की अभिव्यक्ति (अनुक्रम) है आउटपुट वैल्यू पाने के लिए अन्य तत्व।

यहाँ x[[1]] के बराबर है:,

(sin, a+b+1) 

या, और अधिक विस्तार में

(sin, (+, a, (+, b, 1))). 

इस प्रकार, x[[1]][2] ऊपर केवल 2 तत्व और रिटर्न से मिलकर की किसी परिणाम को ले जाता है:

((+, a, (+, b, 1))) 

(यानी (a+b+1)() - कोई तर्क नहीं!)।दूसरी ओर x[[1]][[2]] अर्क पर (अंदर दिखता है) 2 तत्व और देता है:

(+, एक, (+, बी, 1)),

अर्थात a+b+1 (ध्यान दें कम कोष्ठक की एक जोड़ी)।

EDIT2: यह सब आर भाषा की कम से कम IMHO की सुंदरता और अभिव्यक्ति का उदाहरण देता है। चलो एक और उदाहरण है जिसमें हम एक फोन f1(f2(f3, f4), f3, f4), जो एक दृश्य द्वारा प्रस्तुत किया जा सकता बनाने का अध्ययन करते हैं

(f1, (f2, f3, f4), f3, f4). 

हम:

f <- function(...) invisible(NULL) 
f1 <- f; f2 <- f; f3 <- f; f4 <- f # for sake of clarity below 
expr <- quote(f1(f2(f3, f4), f3, f4)) 
print(expr) 
## f1(f2(f3, f4), f3, f4),   i.e. (f1, (f2, f3, f4), f3, f4) 
print(expr[1:3]) 
## f1(f2(f3, f4), f3),    i.e. (f1, (f2, f3, f4), f3) 
print(expr[3:4]) 
## f3(f4),       i.e. (f3, f4) 
print(expr[3]) 
## f3(),        i.e. (f3) 
expr[2] 
## f2(f3, f4)(),      i.e. ((f2, f3, f4)) [subsetting!] 

और अब कुछ पूरी तरह से अलग के लिए:

expr[[2]] 
## f2(f3, f4),      i.e. (f2, f3, f4) [extraction] 

उम्मीद है कि यह इन मुद्दों को थोड़ा सा स्पष्ट करता है।

+0

दोनों वर्ग (एक्स [[1]] [[2]]) और कक्षा (एक्स [[1]] [2]) कॉल हैं। – qed

+3

एक आपको '(ए + बी + 1)()' और दूसरा एक '+ "(ए," + "(बी, 1)) पर कॉल देता है। – gagolews

+1

मैंने कुछ संपादन किए हैं, उम्मीद है कि यह इस जटिल विषय को और अधिक स्पष्ट करता है। :) – gagolews

संबंधित मुद्दे