2011-05-19 21 views
6

मैं समझने के लिए संघर्ष कर रहा हूं कि यह क्यों काम नहीं करता है।फ़ंक्शन के अंदर/अंदर कैसे उपयोग करें?

df <- data.frame(a=1:10, b=1:10) 

foo <- function(obj, col) { 
    with(obj, ls()) 
    with(obj, print(col)) 
} 
foo(df, a) 

[1] "एक" "बी" प्रिंट में

त्रुटि (col): वस्तु 'एक' नहीं मिला

ऐसा करता है काम:

with(df, print(a)) 
+1

यह संभवतः आप जो करने की कोशिश कर रहे हैं उसके बारे में व्यापक संदर्भ रखने में मदद करेंगे। –

उत्तर

12

with से उपयोगी है और एक में पठनीयता में सुधार इंटरैक्टिव संदर्भ लेकिन आपके मस्तिष्क को एक प्रोग्रामिंग संदर्भ में चोट पहुंचा सकता है जहां आप काम करने के लिए आगे और आगे काम कर रहे हैं और विभिन्न वातावरण में चीजों से निपटने के लिए। आम तौर पर आर के भीतर, नामों के बजाय प्रतीकों का उपयोग करना "अर्थात् चीनी" का एक प्रकार है जो इंटरैक्टिव उपयोग में सुविधाजनक और पठनीय है लेकिन प्रोग्रामिंग के लिए हल्के से बहिष्कृत है [उदा। $, subset])। आप बल्कि एक प्रतीक (a) की तुलना में जहाँ तक एक नाम ("a") का उपयोग कर के रूप में समझौता करने को तैयार कर रहे हैं तो मैं बजाय सरल obj[[col]] पर वापस गिरने यहाँ with का उपयोग कर ...

तो, एक स्वयं के रूप में सुझाव है कि -contained जवाब:

foo <- function(object,col) { 
    print(names(object)) 
    print(object[[col]]) 
} 

यदि आप एकाधिक स्तंभों के लिए अनुमति देने के लिए करना चाहता था (यानी एक चरित्र वेक्टर)

foo <- function(object,col) { 
    print(names(object)) 
    print(object[col]) 
} 

संपादित: refra एक फ़ंक्शन के साथ subset का उपयोग करने से, 0 हैडली के सुझाव

(यह एक डेटा फ्रेम के रूप में उत्तर प्रिंट करेगा, भले ही एक कॉलम चुना गया हो, जो हो सकता है कि आप जो भी चाहते हों)।

+0

मेरा जवाब हटा दिया गया है, इसलिए आप रेफ़रल को बदलना चाहेंगे। और चेतावनी के लिए +1। –

+0

सभी उत्तरों के लिए धन्यवाद। मैं वास्तव में कुछ भी प्रिंट करने की कोशिश नहीं कर रहा हूं, मैं सिर्फ कॉलम पर अन्य कार्यों में पास करने में सक्षम होना चाहता हूं। सबसेट जैसी फ़ंक्शंस को देखते हुए जो चरम नामों के रूप में कॉलम लेते हैं, स्ट्रिंग नहीं, मैंने सोचा कि ऐसा करना आसान होगा। मुझे लगता है कि मैं स्ट्रिंग्स पर गुजरने के साथ रहूंगा। :) – rafalotufo

+0

किसी फ़ंक्शन के अंदर सबसेट का उपयोग करने के अलावा खराब फॉर्म है, क्योंकि यदि आप कॉलम की अपेक्षा नहीं करते हैं तो आपको भ्रमित त्रुटि संदेश मिलेंगे - सीधे सबसेटिंग का उपयोग करना बेहतर होगा। प्रश्न के उत्तर देने के लिए – hadley

4

किसी भी कार्य को पारित किया गया कुछ भी एक वस्तु, एक स्ट्रिंग या संख्या होना चाहिए। इसके साथ दो समस्याएं हैं:

  1. इस मामले में आप एक वस्तु के रूप में "ए" को पारित करने का प्रयास कर रहे हैं, जब आपको वास्तव में इसे एक स्ट्रिंग की तरह गुजरना चाहिए।
  2. के साथ (ओबीजे, एलएस())) फ़ंक्शन पर्यावरण (फ़ंक्शन स्कोपिंग) पर वापस आ जाएंगे, न कि जब तक आप इसे मुद्रित नहीं करते हैं तब तक स्क्रीन नहीं।

तुम क्या चाहते अधिक की तरह है:

foo <- function(obj, col) { 
     print(with(obj, ls())) 
     with(obj, print(obj[[col]])) 
    } 

foo(df, "a") 

या यदि आप केवल एक स्तंभ के लिए देख रहे मुद्रित करने के लिए:

foo <- function(obj, col) { 
      with(obj, print(obj[[col]])) 
     } 

foo(df, "a") 
+0

लेकिन वह वह नहीं चाहता जो वह चाहता है: वह चाहता है कि डीएफ $ एक मुद्रित हो। –

+0

यह अस्पष्ट है कि वह मुद्रित करना चाहता है। मेरे लिए ऐसा लगता है कि वह दो लाइनों को मुद्रित करना चाहता है। एक निर्दिष्ट कॉलम की सामग्री के साथ ओबीजे और दूसरे के उपनाम के साथ एक। –

1

फ़ंक्शन तर्क कॉल में फ़ंक्शन में उपयोग करने से पहले मूल्यांकन किया जाता है (इंटरैक्टिव उपयोग के विपरीत)। यहां आपके पास इस समस्या के दो समाधान हैं।

foo1 <- function(obj, col) { 
      with(obj, print(eval(col))) 
     } 
foo1(mydf, quote(a))# here you have to remember to quote argument 


foo2 <- function(obj, col) { 
      col <- as.expression(as.name(substitute(col)))#corrected after DWIN comment 
      with(obj, print(eval(col))) 
     } 
foo2(mydf, a)# this function does all necessary stuff 
+0

+1, हालांकि मुझे अभी भी लगता है कि/eval/etc के साथ गड़बड़ है। इस तरह से एक बुरा विचार है ... –

+0

मैं उन्हें काम करने के लिए दूसरा नहीं मिला। आम तौर पर जब आप 'eval' का उपयोग करते हैं, तो आपको एक पर्यावरण निर्दिष्ट करने की आवश्यकता होती है। –

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