यह उत्तर मौजूदा उत्तर के रूप में समान तत्वों में से कई को कवर करेगा, लेकिन यह मुद्दा (कार्यों के लिए स्तंभ नाम पारित करना) अक्सर पर्याप्त होता है कि मैं चाहता था कि एक ऐसा उत्तर हो जो चीजों को थोड़ा अधिक व्यापक रूप से कवर करता हो।
मान लें कि हमारे पास एक बहुत ही सरल डेटा फ़्रेम है:
dat <- data.frame(x = 1:4,
y = 5:8)
और हम एक फ़ंक्शन लिखना चाहते हैं जो एक नया कॉलम बनाता z
है जो कॉलम x
और का योग है y
।
यहां एक बहुत ही सामान्य ठोकर है कि एक प्राकृतिक (लेकिन गलत) प्रयास अक्सर ऐसा दिखता है:
foo <- function(df,col_name,col1,col2){
df$col_name <- df$col1 + df$col2
df
}
#Call foo() like this:
foo(dat,z,x,y)
यहाँ समस्या यह है कि df$col1
अभिव्यक्ति का मूल्यांकन नहीं करता है col1
। यह केवल df
शब्दशः कहे जाने वाले कॉलम के लिए दिखता है col1
। यह व्यवहार ?Extract
"पुनरावर्ती (सूची-जैसा) ऑब्जेक्ट्स" अनुभाग के तहत वर्णित है ।
सरल, और सबसे अधिक बार सुझाए गए समाधान के बस से स्विच कर रहा है $
करने के लिए [[
तारों के रूप में और समारोह तर्क पारित:
new_column1 <- function(df,col_name,col1,col2){
#Create new column col_name as sum of col1 and col2
df[[col_name]] <- df[[col1]] + df[[col2]]
df
}
> new_column1(dat,"z","x","y")
x y z
1 1 5 6
2 2 6 8
3 3 7 10
4 4 8 12
इसे अक्सर "सर्वश्रेष्ठ अभ्यास" माना जाता है क्योंकि यह एक ऐसी विधि है जिसे पेंच करना सबसे कठिन है। स्तंभ नामों को तार के रूप में पारित करना लगभग उतना ही अस्पष्ट है जितना आप प्राप्त कर सकते हैं।
निम्नलिखित दो विकल्प अधिक उन्नत हैं। कई लोकप्रिय पैकेज इस प्रकार की तकनीकों का उपयोग करते हैं, लेकिन उन्हें अच्छी तरह से उपयोग करने के लिए अधिक देखभाल और कौशल की आवश्यकता होती है, क्योंकि वे सूक्ष्म जटिलताओं और असफलता के अप्रत्याशित बिंदुओं को पेश कर सकते हैं। हेडली की एडवांस्ड आर बुक का यह खंड इन मुद्दों में से कुछ के लिए एक उत्कृष्ट संदर्भ है।
यदि आप वास्तव में उपयोगकर्ता को उन सभी उद्धरणों को टाइप करने से बचाना चाहते हैं, तो एक विकल्प नंगे, बिना कॉलम वाले नामों को स्ट्रिंग में बदलना हो सकता है deparse(substitute())
:
new_column2 <- function(df,col_name,col1,col2){
col_name <- deparse(substitute(col_name))
col1 <- deparse(substitute(col1))
col2 <- deparse(substitute(col2))
df[[col_name]] <- df[[col1]] + df[[col2]]
df
}
> new_column2(dat,z,x,y)
x y z
1 1 5 6
2 2 6 8
3 3 7 10
4 4 8 12
यह, स्पष्ट रूप से, शायद थोड़ा मूर्खतापूर्ण है, क्योंकि हम वास्तव में एक ही काम कर रहे हैं new_column1
, अतिरिक्त कार्यों के एक गुच्छा के साथ नंगे नामों को तार में बदलने के लिए।
अंत में, यदि हम वास्तव में कल्पना करना चाहते हैं, तो हम यह तय कर सकते हैं कि जोड़ने के लिए दो कॉलम के नामों को पारित करने के बजाय, हम और अधिक लचीला होना चाहते हैं और दो चर के अन्य संयोजनों के लिए अनुमति देते हैं। उस स्थिति में हम संभवतः eval()
दो स्तंभों को शामिल करते हुए अभिव्यक्ति का उपयोग कर सकते हैं:
new_column3 <- function(df,col_name,expr){
col_name <- deparse(substitute(col_name))
df[[col_name]] <- eval(substitute(expr),df,parent.frame())
df
}
बस मनोरंजन के लिए, मैं अभी भी deparse(substitute())
नए कॉलम के नाम का उपयोग कर रहा हूं । यहाँ, निम्नलिखित सभी काम करेंगे:
> new_column3(dat,z,x+y)
x y z
1 1 5 6
2 2 6 8
3 3 7 10
4 4 8 12
> new_column3(dat,z,x-y)
x y z
1 1 5 -4
2 2 6 -4
3 3 7 -4
4 4 8 -4
> new_column3(dat,z,x*y)
x y z
1 1 5 5
2 2 6 12
3 3 7 21
4 4 8 32
तो संक्षिप्त उत्तर मूल रूप से है: स्ट्रिंग के रूप में data.frame स्तंभ नामों को पास [[
करें और एकल कॉलम का चयन करने के लिए उपयोग करें। केवल में जाने पर शुरू eval
, substitute
आदि यदि आप वास्तव में पता है कि तुम क्या कर रहे हैं।