2012-10-19 3 views
50

हर किसी के कार्य फॉर्मूला ऑब्जेक्ट्स लेते हैं और फिर अंधेरे जादू को कहीं गहरे अंदर करते हैं और मैं ईर्ष्यावान हूं।प्रोग्रामिंग रूप से सूत्र बनाने के लिए स्ट्रिंग मैनिपुलेशन से बेहतर विकल्प है?

मैं एक ऐसा फ़ंक्शन लिख रहा हूं जो कई मॉडलों को फिट करता है। इन मॉडलों के सूत्रों के भाग एक ही रहते हैं और एक मॉडल से अगले मॉडल में भाग बदलते हैं। बेवकूफ तरीका उपयोगकर्ता को फॉर्मूला भागों को चरित्र तारों के रूप में इनपुट करना होगा, उन पर कुछ चरित्र कुशलता करें, और फिर as.formula का उपयोग करें।

लेकिन मैं उस मार्ग पर जाने से पहले, मैं बस यह सुनिश्चित करना चाहता हूं कि मैं ऐसा करने के कुछ क्लीनर तरीके को नहीं देख रहा हूं जो फ़ंक्शन को मानक आर प्रारूप में सूत्रों को स्वीकार करने की अनुमति देगा (उदाहरण के लिए अन्य सूत्र से निकाले गए वस्तुओं)।

मैं कुछ चाहते हैं की तरह ...

> LHS <- y~1; RHS <- ~a+b; c(LHS,RHS); 
y ~ a + b 
> RHS2 <- ~c; 
> c(LHS, RHS, RHS2); 
y ~ a + b + c 

या ...

> LHS + RHS; 
y ~ a + b 
> LHS + RHS + RHS2; 
y ~ a + b + c 

... लेकिन दुर्भाग्य से न वाक्य रचना काम करता है। क्या कोई जानता है कि ऐसा कुछ है जो करता है? धन्यवाद।

+0

भले ही मैं यह महसूस कर रहा हूं कि मुझे सामान्यता के उस स्तर की आवश्यकता नहीं है और इसके बजाय 'अपडेट' फ़ंक्शन का बेहतर उपयोग किया गया है, तो नीचे दिए गए मनेल का उत्तर एक अच्छा और उपयोगी है, और हो सकता है मैं मूल रूप से प्रयास कर रहा था। आम तौर पर, हालांकि, मैं अच्छे उत्तरों को ऊपर उठाता हूं लेकिन उन्हें तब तक स्वीकार नहीं करता जब तक कि मैं वास्तव में उनको कोशिश नहीं करता और उनके लिए झुका सकता हूं। कई मामलों में मुझे अपने आप पर बेहतर उत्तर मिलते हैं और जब मेरे पास समय होता है तो वास्तव में आत्म-उत्तर सबमिट करना चाहिए। क्या मैं उत्तर स्वीकार करने के लिए अपने मानदंडों में भी कठोर हूं? आपके महान सारांश के लिए – f1r3br4nd

उत्तर

62

reformulate जो भी आप चाहते हैं वह करेंगे।

reformulate(termlabels = c('x','z'), response = 'y') 
## y ~ x + z 

या एक अवरोधन

reformulate(termlabels = c('x','z'), response = 'y', intercept = FALSE) 
## y ~ x + z - 1 

ध्यान दें कि आप एक से अधिक के साथ सूत्रों का निर्माण नहीं कर सकते reponses जैसे x+y ~z+b

reformulate(termlabels = c('x','y'), response = c('z','b')) 
z ~ x + y 

एक मौजूदा formula (अपने उदाहरण दिया गया है) से शब्दों को निकालने के लिए बिना

attr(terms(RHS), 'term.labels') 
## [1] "a" "b" 

प्रतिक्रिया प्राप्त करने के लिए थोड़ा अलग है, एक साधारण दृष्टिकोण (एक परिवर्तनीय प्रतिक्रिया के लिए)। , जैसे

combine_formula2 <- function(response, RHS, intercept = TRUE){ 
    .terms <- lapply(RHS, terms) 
    new_terms <- unique(unlist(lapply(.terms, attr, which = 'term.labels'))) 
    response <- as.character(LHS)[2] 

    reformulate(new_terms, response, intercept) 


} 
combine_formula2('y', list(RHS, RHS2)) 

कुछ

as.character(LHS)[2] 
## [1] 'y' 


combine_formula <- function(LHS, RHS){ 
    .terms <- lapply(RHS, terms) 
    new_terms <- unique(unlist(lapply(.terms, attr, which = 'term.labels'))) 
    response <- as.character(LHS)[2] 

    reformulate(new_terms, response) 


} 


combine_formula(LHS, list(RHS, RHS2)) 

## y ~ a + b + c 
## <environment: 0x577fb908> 

मुझे लगता है कि इसे और अधिक एक चरित्र वेक्टर के रूप में प्रतिक्रिया निर्दिष्ट करने के लिए समझदार होगा आप भी सूत्रों के साथ काम करने के लिए एक + ऑपरेटर निर्धारित कर सकते हैं (अद्यतन के लिए एक नई विधि की स्थापना सूत्र वस्तुओं)

`+.formula` <- function(e1,e2){ 
    .terms <- lapply(c(e1,e2), terms) 
    reformulate(unique(unlist(lapply(.terms, attr, which = 'term.labels')))) 
} 

RHS + RHS2 
## ~a + b + c 

तुम भी उपयोग कर सकते हैं update.formula. विवेकपूर्ण तरीके का उपयोग कर

update(~a+b, y ~ .) 
## y~a+b 
+9

+1। लेकिन आइए इसे स्वीकार करें: यह केवल दिखाता है कि तारों के माध्यम से दृष्टिकोण का उपयोग करना है यदि आप कोड को पढ़ने में आसान चाहते हैं।मुझे संदेह है कि, जीवनभर में सम्मिलित, गति में लाभ आपको कॉफी के लिए समय खरीदता है। –

+16

@DieterMenne गति में लाभ असीमित है - सुरक्षा में लाभ महत्वपूर्ण है। पहली बार जब कोई गैर-सिंटैक्टिक वैरिएबल नाम (यानी "ए बी") के साथ आपके कोड का उपयोग करने का प्रयास करता है तो यह एक अजीब त्रुटि के साथ टूट जाएगा जो आपको ढूंढने के लिए घंटों और घंटे लगेगा। – hadley

+0

क्या 'update.formula' के मुकाबले' .' का उपयोग करने का कोई और तरीका है? मैं 'setdiff() 'कथन का उपयोग करके समाप्त हुआ जहां मुझे' reform। (Var'' में '~।-Var1-var2' का उपयोग करना पसंद होता, और सहायता उस मामले का उपयोग नहीं करती है। –

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