2015-09-16 7 views
12

के भीतर उपयोग के लिए एक इंफिक्स ऑपरेटर को परिभाषित करना मैं this समाधान का एक अधिक पारदर्शी संस्करण बनाने की कोशिश कर रहा हूं, जिसमें d1 + d1:d2 रूप में सूत्र के आरएचएस को निर्दिष्ट करना शामिल है।एक सूत्र

यह देखते हुए कि एक सूत्र के संदर्भ में * एक सारगर्भित स्टैंड में पूर्ण बातचीत के लिए है (यानी d1 * d2d1 + d2 + d1:d2 देता है), मेरे दृष्टिकोण कोशिश करते हैं और एक वैकल्पिक ऑपरेटर परिभाषित करने के लिए किया गया है, इन्फ़िक्स दृष्टिकोण मैंने का उपयोग कर %+:% कहना अन्य अनुप्रयोगों में के आदी हो गए, एक ला:

"%+:%" <- function(d1,d2) d1 + d2 + d1:d2 

बहरहाल, यह जाहिर विफल रहता है, क्योंकि मैं नहीं किया है मूल्यांकन के बारे में सावधान कर दिया गया; मेरा प्रगति को वर्णन करने के लिए एक उदाहरण परिचय करते हैं:

set.seed(1029) 
v1 <- runif(1000) 
v2 <- runif(1000) 
y <- .8*(v1 < .3) + .2 * (v2 > .25 & v2 < .8) - 
    .4 * (v2 > .8) + .1 * (v1 > .3 & v2 > .8) 

इस उदाहरण के साथ, उम्मीद है कि यह स्पष्ट है क्यों बस दो शब्दों लिखने अवांछनीय हो सकता है:

y ~ cut(v2, breaks = c(0, .25, .8, 1)) + 
    cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3) 

एक वैकल्पिक हल जो मेरे वांछित आउटपुट के करीब है एक समारोह के रूप में पूरे सूत्र परिभाषित करने के लिए है:

plus.times <- function(outvar, d1, d2){ 
    as.formula(paste0(quote(outvar), "~", quote(d1), 
        "+", quote(d1), ":", quote(d2))) 
} 

यह जब lm के लिए पारित कर देता है उम्मीद गुणांक, लेकिन नाम के साथ कि एक कठिन फिर से सीधे व्याख्या करने के लिए (विशेष रूप से वास्तविक डेटा जहां हम देखभाल d1 और d2 वर्णनात्मक नाम इस सामान्य उदाहरण के विपरीत, देने के लिए):

out1 <- lm(y ~ cut(v2, breaks = c(0, .25, .8, 1)) + 
      cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3)) 
out2 <- lm(plus.times(y, cut(v2, breaks = c(0, .25, .8, 1)), I(v1 < .3))) 
any(out1$coefficients != out2$coefficients) 
# [1] FALSE 
names(out2$coefficients) 
# [1] "(Intercept)"   "d1(0.25,0.8]"  "d1(0.8,1]"   "d1(0,0.25]:d2TRUE" 
# [5] "d1(0.25,0.8]:d2TRUE" "d1(0.8,1]:d2TRUE" 

तो यह इष्टतम से कम है।

वहाँ इतना है कि इन्फ़िक्स ऑपरेटर मैं उपर्युक्त अपेक्षा के अनुरूप काम करता है कोड को समायोजित परिभाषित करने के लिए कोई तरीका है? कैसे plus.times के रूप बदलकर देखें कि चर का नाम बदला नहीं कर रहे हैं के बारे में?

मैं चारों ओर (?formula, ?"~", ?":", getAnywhere(formula.default), this जवाब, आदि) poking किया गया है, लेकिन नहीं देखा है कि कैसे वास्तव में आर व्याख्या * जब यह एक सूत्र में सामना करना पड़ा है ताकि मैं अपने वांछित मामूली समायोजन कर सकते हैं ।

+0

वे आँकड़े से व्याख्या कर रहे हैं ::: ग में model.frame.default https://github.com/wch/r-source/blob/ed66b715221d2720f5b334470335635bada520b1/src/library/stats/src/model.c#L888 – rawr

+0

@rawr धन्यवाद। यह नहीं कह सकता कि मुझे पता है कि सी कोड में क्या हो रहा है - मुझे लगता है कि वे 'फॉर्मूला' द्वारा समझा जाने वाले प्रत्येक प्रतीक को "परिभाषित" करते हैं लेकिन वे केवल 'tildeSymbol' का उपयोग करते हैं। क्या इसका मतलब यह है कि मैं सी और परिभाषित करने के बिना अपने स्वयं के इंफिक्स प्राप्त नहीं कर पाऊंगा, कहें कि 'प्लसकोलन सिंबल' जैसा यहां किया गया है? – MichaelChirico

+1

@ हीदर टर्नर का जवाब मेरे लिए बिल्कुल सही लगता है। यदि आप वास्तव में विस्तारित सूत्रों के साथ गड़बड़ करना शुरू करना चाहते हैं, तो मैं सुझाव दूंगा कि (1) 'model.frame()' के परिणामों के 'नियम' घटक को देखकर और (2) कोड को देखकर [यहां] (https) : //github.com/glmmTMB/glmmTMB/blob/master/glmmTMB/R/utils.R) ... –

उत्तर

6

आपको इस मामले में एक नया ऑपरेटर परिभाषित करने की आवश्यकता नहीं है: सूत्र में d1/d2d1 + d1:d2 तक फैला है। दूसरे शब्दों में d1/d2 निर्दिष्ट करता है कि d2d1 भीतर नीडिंत है। अपने उदाहरण को जारी:

out3 <- lm(y ~ cut(v2,breaks=c(0,.25,.8,1))/I(v1 < .3)) 
all.equal(coef(out1), coef(out3)) 
# [1] TRUE 

इसके अलावा टिप्पणी

कारक पार या नेस्टेड हो सकता है। अगर यह संभव दो कारकों के स्तर के प्रत्येक संयोजन के निरीक्षण करने के लिए दो कारक पार नहीं है, उदा सेक्स और उपचार, तापमान और पीएच, आदि एक कारक एक और अंदर नीडिंत है कि कारक के प्रत्येक स्तर केवल अन्य कारक, जैसे की स्तरों में से एक के भीतर देखा जा सकता है अगर शहर और देश, स्टाफ सदस्य और दुकान आदि

इन रिश्तों मॉडल की parametrization में परिलक्षित होते हैं।पार कारकों के लिए हम d1*d2 या d1 + d2 + d1:d2 का उपयोग करते हैं, ताकि प्रत्येक कारक का मुख्य प्रभाव, साथ ही बातचीत भी हो सके। नेस्टेड कारकों के लिए हम d1/d2 या d1 + d1:d2 का उपयोग 1 + d2 के प्रत्येक स्तर के d1 के एक अलग सबमिडेल देने के लिए करते हैं।

घोंसले का विचार कारकों तक ही सीमित नहीं है, उदाहरण के लिए हम sex/x का उपयोग कर सकते हैं ताकि पुरुषों और महिलाओं के लिए x पर एक अलग रैखिक प्रतिगमन फिट हो सके।

एक सूत्र में, %in%: के बराबर है, लेकिन इसका उपयोग डेटा/मॉडल की नेस्टेड, या पदानुक्रमित संरचना पर जोर देने के लिए किया जा सकता है। उदाहरण के लिए, a + b %in% aa + a:b जैसा ही है, लेकिन इसे "ए प्लस बी इन ए" के रूप में पढ़ना मॉडल के बेहतर विवरण देता है। फिर भी, / का उपयोग करके संरचना पर जोर देने के साथ ही मॉडल सूत्र को सरल बनाने का लाभ होता है।

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