r - आर में उच्च स्तर के कार्य-क्या कोई आधिकारिक रचना ऑपरेटर या करी फ़ंक्शन है?




functional-programming higher-order-functions (3)

आर में कार्यात्मक प्रोग्रामिंग के लिए मानक स्थान अब functional पुस्तकालय है।

पुस्तकालय से:

कार्यात्मक: करी, रचना और अन्य उच्च-क्रम के कार्य

उदाहरण:

   library(functional)
   newfunc <- Curry(oldfunc,x=5)

CRAN: https://cran.r-project.org/web/packages/functional/index.html

पुनश्च: यह पुस्तकालय ROxigen पुस्तकालय का विकल्प है।

मैं R में कंपोज़ ऑपरेटर बना सकता हूं:

 `%c%` = function(x,y)function(...)x(y(...)) 

इस तरह इस्तेमाल किया जाना है:

 > numericNull = is.null %c% numeric
 > numericNull(myVec)
 [2] TRUE FALSE

लेकिन मैं यह जानना चाहूंगा कि क्या इस तरह के काम करने के लिए कार्यों का एक आधिकारिक सेट है और अन्य संचालन जैसे कि आर। में करी करना। यह मेरे कोड में कोष्ठक, फ़ंक्शन कीवर्ड आदि की संख्या को कम करना है।

मेरी करी समारोह:

> curry=function(...){
    z1=z0=substitute(...);z1[1]=call("list");
    function(...){do.call(as.character(z0[[1]]),
                          as.list(c(eval(z1),list(...))))}}
> p = curry(paste(collapse=""))
> p(letters[1:10])
[1] "abcdefghij"

यह विशेष रूप से उदाहरण के लिए अच्छा है:

> df = data.frame(l=sample(1:3,10,rep=TRUE), t=letters[1:10])
> aggregate(df$t,df["l"],curry(paste(collapse="")) %c% toupper)
  l    x
1 1  ADG
2 2  BCH
3 3 EFIJ

जो मुझे बहुत अधिक सुंदर और संपादन योग्य लगता है:

> aggregate(df$t, df["l"], function(x)paste(collapse="",toupper(x)))
  l    x
1 1  ADG
2 2  BCH
3 3 EFIJ

मूल रूप से मैं जानना चाहता हूं - क्या यह पहले से ही आर के लिए किया गया है?


यदि आप चाहते हैं कि चर के 'नाम' सही तरीके से गुजरें तो अधिक जटिल दृष्टिकोण की आवश्यकता होती है।

उदाहरण के लिए, यदि आप plot(rnorm(1000),rnorm(1000)) तो आपको अपने x- और y- अक्षों पर अच्छे लेबल मिलेंगे। इसका एक और उदाहरण data.frame

> data.frame( rnorm(5), rnorm(5), first=rpois(5,1), second=rbinom(5,1,0.5) )
    rnorm.5. rnorm.5..1 first second
1  0.1964190 -0.2949770     0      0
2  0.4750665  0.8849750     1      0
3 -0.7829424  0.4174636     2      0
4  1.6551403  1.3547863     0      1
5  1.4044107 -0.4216046     0      0

ऐसा नहीं है कि डेटा.फ्रेम ने कॉलमों को उपयोगी नाम दिए हैं।

करी के कुछ कार्यान्वयन ठीक से ऐसा नहीं कर सकते हैं, जिससे अपठनीय स्तंभ नाम और प्लॉट लेबल हो सकते हैं। इसके बजाय, मैं अब कुछ इस तरह का उपयोग करें:

Curry <- function(FUN, ...) {
    .orig = match.call()
    .orig[[1]] <- NULL # Remove first item, which matches Curry
    .orig[[1]] <- NULL # Remove another item, which matches FUN
    function(...) {
        .inner = match.call()
        .inner[[1]] <- NULL # Remove first item, which matches Curry
        do.call(FUN, c(.orig, .inner), envir=parent.frame())
    }
}

यह काफी जटिल है, लेकिन मुझे लगता है कि यह सही है। match.call सभी match.call को पकड़ लेगा, पूरी तरह से याद match.call कि किन शब्दों ने match.call को परिभाषित किया (यह अच्छे लेबल के लिए आवश्यक है)। समस्या यह है कि यह बहुत सारे args पकड़ता है - न केवल ... बल्कि FUN भी। यह उस फ़ंक्शन का नाम भी याद रखता है जिसे कॉल किया जा रहा है ( Curry )।

इसलिए, हम इन पहली दो प्रविष्टियों को .orig में हटाना चाहते हैं ताकि .orig वास्तव में सिर्फ ... तर्कों से मेल खाती हो। इसलिए हम करते हैं .orig[[1]]<-NULL दो बार - हर बार एक प्रविष्टि को हटाता है और बाकी सब को बाईं ओर शिफ्ट करता है।

यह परिभाषा पूरी करता है और अब हम उपरोक्त के समान ही प्राप्त करने के लिए निम्न कार्य कर सकते हैं

Curry(data.frame, rnorm(5), rnorm(5) )( first=rpois(5,1) , second=rbinom(5,1,0.5) )

envir=parent.frame() पर एक अंतिम नोट। मैंने यह सुनिश्चित करने के लिए इसका उपयोग किया कि यदि आपके पास '.inner' या '.orig' नामक बाहरी चर हैं तो कोई समस्या नहीं होगी। अब, सभी चरों का मूल्यांकन उस स्थान पर किया जाता है जहाँ करी को बुलाया जाता है।








higher-order-functions