समूहन कार्य (tapply, by, समुच्चय) और * परिवार को लागू करें


1040

जब भी मैं आर में कुछ "मैप" पी करना चाहता हूं, तो मैं आमतौर पर applyपरिवार में एक फ़ंक्शन का उपयोग करने की कोशिश करता हूं ।

हालाँकि, मैंने कभी भी उनके बीच के अंतरों को नहीं समझा है - कैसे { sapply, lapplyइत्यादि} फ़ंक्शन को इनपुट / समूहीकृत इनपुट पर लागू करते हैं, आउटपुट कैसा दिखेगा, या इनपुट क्या हो सकता है - इसलिए मैं अक्सर बस उन सभी के माध्यम से जाना जब तक मुझे वह नहीं मिलता जो मैं चाहता हूं।

क्या कोई समझा सकता है कि किसका उपयोग कब करना है?

मेरी वर्तमान (शायद गलत / अपूर्ण) समझ है ...

  1. sapply(vec, f): इनपुट एक वेक्टर है। आउटपुट एक वेक्टर / मैट्रिक्स है, जहां तत्व iहै f(vec[i]), जो आपको fएक मल्टी-एलिमेंट आउटपुट होने पर मैट्रिक्स देता है

  2. lapply(vec, f): के रूप में ही है sapply, लेकिन उत्पादन एक सूची है?

  3. apply(matrix, 1/2, f): इनपुट एक मैट्रिक्स है। आउटपुट एक वेक्टर है, जहां तत्व if (मैट्रिक्स की पंक्ति / कॉलोनी) है
  4. tapply(vector, grouping, f): आउटपुट एक मैट्रिक्स / सरणी है, जहां मैट्रिक्स / सरणी में एक तत्व वेक्टर के fसमूहीकरण पर मूल्य है g, और gपंक्ति / कॉल नाम पर धकेल दिया जाता है
  5. by(dataframe, grouping, f): gसमूहन होने दो । fसमूह के प्रत्येक कॉलम / डेटाफ्रेम पर लागू होते हैं । सुंदर fप्रत्येक समूह में समूहीकरण और मूल्य को प्रिंट करें।
  6. aggregate(matrix, grouping, f): के समान है by, लेकिन आउटपुट प्रिंट करने के बजाय, एग्रीगेट डेटाफ़्रेम में सब कुछ चिपक जाता है।

साइड सवाल: मैंने अभी भी प्लाई या रिशेप नहीं सीखा है - plyrया reshapeइन सभी को पूरी तरह से बदल देगा ?


33
आपके पक्ष के प्रश्न के लिए: कई चीजों के लिए प्लाई प्रत्यक्ष प्रतिस्थापन है *apply()और by। plyr (कम से कम मेरे लिए) इसमें बहुत अधिक सुसंगत लगता है कि मुझे हमेशा पता है कि यह किस डेटा प्रारूप की अपेक्षा करता है और वास्तव में यह क्या कहेगा। जिससे मुझे बहुत परेशानी होती है।
JD लॉन्ग

12
इसके अलावा, मैं जोड़ने की सलाह दूंगा: doByऔर चयन और लागू क्षमताओं data.table
इटरेटर

7
sapplyबस है lapplyके अलावा के साथ simplify2arrayउत्पादन पर। applyपरमाणु वेक्टर के लिए मोटे तौर पर करता है, लेकिन आउटपुट वेक्टर या सूची हो सकता है। byडेटाफ़्रेम को उप-डेटाफ़्रेम में विभाजित करता है, लेकिन यह fस्तंभों पर अलग से उपयोग नहीं करता है । यदि 'data.frame' वर्ग के लिए कोई विधि है तो केवल fकॉलम-वार द्वारा लागू किया जा सकता है byaggregateसामान्य है इसलिए पहले तर्क के विभिन्न वर्गों के लिए अलग-अलग विधियाँ मौजूद हैं।
IRTFM

8
Mememonic: l 'सूची' के लिए है, s 'सरलीकृत' के लिए है, t 'प्रति प्रकार' के लिए है (समूह का प्रत्येक स्तर एक प्रकार है)
Lutz Prechelt

वहाँ भी पैकेज में कुछ कार्यों मौजूद Rfast, जैसे: eachcol.apply, apply.condition, और अधिक है, जो तेजी से आर के समकक्ष से कर रहे हैं
Stefanos

जवाबों:


1330

R के पास कई * लागू कार्य होते हैं जो मदद फ़ाइलों (उदाहरण ?apply) में वर्णित हैं । उनमें से काफी हैं, हालांकि, उस शुरुआत का उपयोग करने वालों को यह तय करने में कठिनाई हो सकती है कि उनकी स्थिति के लिए कौन उपयुक्त है या यहां तक ​​कि उन सभी को याद कर रहा है। उनके पास एक सामान्य समझ हो सकती है कि "मुझे यहां एक * लागू फ़ंक्शन का उपयोग करना चाहिए", लेकिन पहले से सीधे उन सभी को रखना मुश्किल हो सकता है।

इस तथ्य के बावजूद (अन्य उत्तरों में उल्लेख किया गया है) कि बहुत से कार्यशीलता * लागू परिवार बेहद लोकप्रिय plyrपैकेज द्वारा कवर किया गया है , आधार फ़ंक्शन उपयोगी और जानने योग्य हैं।

यह उत्तर नए उपयोग के लिए एक तरह के साइनपोस्ट के रूप में कार्य करने का इरादा है ताकि उन्हें उनकी विशेष समस्या के लिए कार्य को सही * लागू करने में मदद मिल सके। ध्यान दें, यह है नहीं बस वमन करने का इरादा या आर प्रलेखन की जगह! उम्मीद यह है कि यह उत्तर आपको यह तय करने में मदद करता है कि कौन सा * फंक्शन आपकी स्थिति के अनुसार लागू होता है और फिर यह आप पर निर्भर है कि आप इस पर और क्या शोध करेंगे। एक अपवाद के साथ, प्रदर्शन अंतर को संबोधित नहीं किया जाएगा।

  • लागू करें - जब आप मैट्रिक्स (और उच्च-आयामी एनालॉग्स) की पंक्तियों या स्तंभों के लिए एक फ़ंक्शन लागू करना चाहते हैं; आम तौर पर डेटा फ़्रेम के लिए यह उचित नहीं है क्योंकि यह पहले एक मैट्रिक्स के लिए बाध्य होगा।

    # Two dimensional matrix
    M <- matrix(seq(1,16), 4, 4)
    
    # apply min to rows
    apply(M, 1, min)
    [1] 1 2 3 4
    
    # apply max to columns
    apply(M, 2, max)
    [1]  4  8 12 16
    
    # 3 dimensional array
    M <- array( seq(32), dim = c(4,4,2))
    
    # Apply sum across each M[*, , ] - i.e Sum across 2nd and 3rd dimension
    apply(M, 1, sum)
    # Result is one-dimensional
    [1] 120 128 136 144
    
    # Apply sum across each M[*, *, ] - i.e Sum across 3rd dimension
    apply(M, c(1,2), sum)
    # Result is two-dimensional
         [,1] [,2] [,3] [,4]
    [1,]   18   26   34   42
    [2,]   20   28   36   44
    [3,]   22   30   38   46
    [4,]   24   32   40   48
    

    आप चाहते हैं पंक्ति / स्तंभ साधन या एक 2 डी मैट्रिक्स के लिए रकम तो सुनिश्चित करें कि जांच करने के लिए किया जा अत्यधिक अनुकूलित किया है, बिजली की तेज़ी से colMeans, rowMeans, colSums, rowSums

  • lapply - जब आप बदले में सूची के प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करना चाहते हैं और एक सूची वापस प्राप्त करते हैं।

    यह अन्य * लागू कार्यों में से कई का वर्कहॉर्स है। उनके कोड को वापस छीलें और आप अक्सर lapplyनीचे पाएंगे ।

    x <- list(a = 1, b = 1:3, c = 10:100) 
    lapply(x, FUN = length) 
    $a 
    [1] 1
    $b 
    [1] 3
    $c 
    [1] 91
    lapply(x, FUN = sum) 
    $a 
    [1] 1
    $b 
    [1] 6
    $c 
    [1] 5005
    
  • sapply - जब आप बदले में किसी सूची के प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करना चाहते हैं, लेकिन आप सूची के बजाय एक वेक्टर वापस चाहते हैं ।

    यदि आप स्वयं को टाइप करते हुए पाते हैं unlist(lapply(...)), तो रुकें और विचार करें sapply

    x <- list(a = 1, b = 1:3, c = 10:100)
    # Compare with above; a named vector, not a list 
    sapply(x, FUN = length)  
    a  b  c   
    1  3 91
    
    sapply(x, FUN = sum)   
    a    b    c    
    1    6 5005 
    

    इसके अधिक उन्नत उपयोगों में sapply, यदि उपयुक्त हो, तो परिणाम को बहुआयामी सरणी के साथ जोड़ने का प्रयास करेंगे। उदाहरण के लिए, यदि हमारा कार्य समान लंबाई के वैक्टर लौटाता है, तो sapplyवे मैट्रिक्स के कॉलम के रूप में उपयोग करेंगे:

    sapply(1:5,function(x) rnorm(3,x))

    यदि हमारा फ़ंक्शन 2 आयामी मैट्रिक्स लौटाता है, sapplyतो अनिवार्य रूप से एक ही काम करेंगे, प्रत्येक लौटे मैट्रिक्स को एक ही लंबे वेक्टर के रूप में मानते हैं:

    sapply(1:5,function(x) matrix(x,2,2))

    जब तक हम निर्दिष्ट नहीं करते हैं simplify = "array", इस मामले में यह एक बहु-आयामी सरणी बनाने के लिए व्यक्तिगत मैट्रिक्स का उपयोग करेगा:

    sapply(1:5,function(x) matrix(x,2,2), simplify = "array")

    इनमें से प्रत्येक व्यवहार निश्चित रूप से हमारे कार्य पर लौटने वाले वैक्टर या एक ही लंबाई या आयाम के मैट्रीस पर आकस्मिक है।

  • vapply - जब आप उपयोग करना चाहते हैं, sapplyलेकिन शायद अपने कोड से कुछ और गति निचोड़ने की आवश्यकता है।

    इसके लिए vapply, आप मूल रूप से R को एक उदाहरण देते हैं कि आपका कार्य किस प्रकार का होगा, जो एकल परमाणु वेक्टर में फिट होने के लिए लौटाए गए मानों को कुछ समय के लिए बचा सकता है।

    x <- list(a = 1, b = 1:3, c = 10:100)
    #Note that since the advantage here is mainly speed, this
    # example is only for illustration. We're telling R that
    # everything returned by length() should be an integer of 
    # length 1. 
    vapply(x, FUN = length, FUN.VALUE = 0L) 
    a  b  c  
    1  3 91
    
  • mapply - जब आपके पास कई डेटा संरचनाएं (जैसे वैक्टर, सूचियां) होती हैं और आप प्रत्येक के 1 तत्वों के लिए एक फ़ंक्शन लागू करना चाहते हैं, और फिर प्रत्येक के 2 तत्व इत्यादि को एक वेक्टर / सरणी में परिणाम के रूप में शामिल करते हैं। sapply

    यह इस अर्थ में बहुभिन्नरूपी है कि आपके कार्य को कई तर्क स्वीकार करने चाहिए।

    #Sums the 1st elements, the 2nd elements, etc. 
    mapply(sum, 1:5, 1:5, 1:5) 
    [1]  3  6  9 12 15
    #To do rep(1,4), rep(2,3), etc.
    mapply(rep, 1:4, 4:1)   
    [[1]]
    [1] 1 1 1 1
    
    [[2]]
    [1] 2 2 2
    
    [[3]]
    [1] 3 3
    
    [[4]]
    [1] 4
    
  • मानचित्र - एक आवरण के mapplyसाथ SIMPLIFY = FALSE, इसलिए यह एक सूची वापस करने की गारंटी है।

    Map(sum, 1:5, 1:5, 1:5)
    [[1]]
    [1] 3
    
    [[2]]
    [1] 6
    
    [[3]]
    [1] 9
    
    [[4]]
    [1] 12
    
    [[5]]
    [1] 15
    
  • rapply - जब आप किसी नेस्टेड सूची संरचना के प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करना चाहते हैं , पुनरावर्ती रूप से।

    आपको rapplyयह जानने के लिए कि यह कैसे असामान्य है, मैं इस बारे में भूल गया जब पहली बार इस उत्तर को पोस्ट कर रहा था! जाहिर है, मुझे यकीन है कि बहुत से लोग इसका उपयोग करते हैं, लेकिन YMMV। rapplyलागू करने के लिए उपयोगकर्ता द्वारा परिभाषित फ़ंक्शन के साथ सबसे अच्छा चित्रण किया गया है:

    # Append ! to string, otherwise increment
    myFun <- function(x){
        if(is.character(x)){
          return(paste(x,"!",sep=""))
        }
        else{
          return(x + 1)
        }
    }
    
    #A nested list structure
    l <- list(a = list(a1 = "Boo", b1 = 2, c1 = "Eeek"), 
              b = 3, c = "Yikes", 
              d = list(a2 = 1, b2 = list(a3 = "Hey", b3 = 5)))
    
    
    # Result is named vector, coerced to character          
    rapply(l, myFun)
    
    # Result is a nested list like l, with values altered
    rapply(l, myFun, how="replace")
    
  • tapply - जब आप एक वेक्टर के सबसेट के लिए एक फ़ंक्शन लागू करना चाहते हैं और सबसेट को किसी अन्य वेक्टर द्वारा परिभाषित किया जाता है, आमतौर पर एक कारक।

    * की काली भेड़ें परिवार को लागू करती हैं। "रैग्ड ऐरे" वाक्यांश की मदद फ़ाइल का उपयोग थोड़ा भ्रमित कर सकता है , लेकिन यह वास्तव में काफी सरल है।

    एक वेक्टर:

    x <- 1:20

    एक कारक (समान लंबाई का!) परिभाषित समूह:

    y <- factor(rep(letters[1:5], each = 4))

    xद्वारा परिभाषित प्रत्येक उपसमूह के भीतर मान जोड़ें y:

    tapply(x, y, sum)  
     a  b  c  d  e  
    10 26 42 58 74 
    

    कई जटिल उदाहरणों को संभाला जा सकता है जहां उप-समूह को कई कारकों की सूची के अद्वितीय संयोजनों द्वारा परिभाषित किया जाता है। tapplyविभाजन लागू-गठबंधन आर में कार्यों कि आम हैं (करने के लिए आत्मा में इसी तरह की है aggregate, by, ave, ddply, आदि) इसलिए अपनी काली भेड़ स्थिति।


32
लगता है कि आप पाएंगे कि byहै शुद्ध विभाजन lapply और aggregateहै tapplyउनके केंद्र में। मुझे लगता है कि काली भेड़ें शानदार कपड़े बनाती हैं।
IRTFM

21
शानदार प्रतिक्रिया! यह आधिकारिक आर प्रलेखन का हिस्सा होना चाहिए :)। एक छोटा सुझाव: शायद कुछ गोलियों का उपयोग aggregateऔर byसाथ ही करें? (मैं अंत में उन्हें आपके विवरण के बाद समझ सकता हूँ!, लेकिन वे बहुत आम हैं, इसलिए यह अलग करने के लिए उपयोगी हो सकता है और उन दो कार्यों के लिए कुछ विशिष्ट उदाहरण हैं।)
गंभीर

3
@ त्यागुटुर I सक्रिय रूप से इस उत्तर से चीजों को काट रहा था ताकि इसे (ए) बहुत लंबा और (बी) प्रलेखन का फिर से लिखा जा सके। मैंने तय किया कि जबकि aggregate, byआदि * कार्यों पर आधारित हैं, जिस तरह से आप उनका उपयोग कर रहे हैं, वह एक उपयोगकर्ता के दृष्टिकोण से काफी अलग है कि उन्हें एक अलग उत्तर में संक्षेप में प्रस्तुत करना चाहिए। मैं यह कोशिश कर सकता हूं कि अगर मेरे पास समय हो, या हो सकता है कि कोई और मुझे इसके लिए हरा देगा और अपना उत्थान अर्जित करेगा।
जोरन

4
इसके अलावा, ?Mapएक रिश्तेदार के रूप मेंmapply
बपतिस्मा

3
@ जैंडर्स - मैं इससे बिल्कुल सहमत नहीं हूं। data.frames, R का एक बिल्कुल मध्य भाग है और एक listवस्तु के रूप में अक्सर lapplyविशेष रूप से उपयोग करके हेरफेर किया जाता है । वे पारंपरिक आयताकार डाटासेट में एक साथ कई प्रकार के वैक्टर / कारकों को समूहीकृत करने के लिए कंटेनर के रूप में भी कार्य करते हैं। जबकि data.tableऔर plyrएक निश्चित प्रकार का वाक्यविन्यास जोड़ सकता है कि कुछ अधिक आरामदायक मिल सकता है, वे data.frameक्रमशः विस्तार कर रहे हैं और अभिनय कर रहे हैं।
Thelatemail

191

साइड नोट पर, यहां बताया गया है कि कैसे विभिन्न plyrकार्य आधार *applyकार्यों के लिए हैं (परिचय से plyr दस्तावेज़ plyr वेबपेज http://had.co.nz/plyr/ पर )

Base function   Input   Output   plyr function 
---------------------------------------
aggregate        d       d       ddply + colwise 
apply            a       a/l     aaply / alply 
by               d       l       dlply 
lapply           l       l       llply  
mapply           a       a/l     maply / mlply 
replicate        r       a/l     raply / rlply 
sapply           l       a       laply 

इन plyrकार्यों में से प्रत्येक के लिए फ़ंक्शन के नाम में इनपुट और आउटपुट डेटा प्रकार को एन्कोडिंग के लिए लगातार नामकरण परंपराएं प्रदान करना है। यह आउटपुट में निरंतरता भी प्रदान करता है, जिसमें से आउटपुट उपयोगी आउटपुट आदि का उत्पादन dlply()करने के ldply()लिए आसानी से पारित होने योग्य है ।

वैचारिक रूप से, plyrआधार *applyफ़ंक्शंस को समझने की तुलना में सीखना अधिक कठिन नहीं है।

plyrऔर reshapeफ़ंक्शंस ने मेरे हर दिन के उपयोग में इन सभी फ़ंक्शंस को बदल दिया है। लेकिन, इंट्रो से प्लाय डॉक्यूमेंट भी:

संबंधित कार्यों tapplyऔर sweepमें कोई इसी कार्य है plyr, और उपयोगी रहते हैं। mergeमूल डेटा के साथ सारांश के संयोजन के लिए उपयोगी है।


13
जब मैंने खरोंच से आर सीखना शुरू किया तो मुझे *apply()कार्यों के परिवार की तुलना में सीखने में आसानी से मिली । मेरे लिए, ddply()बहुत सहज था क्योंकि मैं एसक्यूएल एकत्रीकरण कार्यों से परिचित था। ddply()कई समस्याओं को हल करने के लिए मेरा हथौड़ा बन गया, जिनमें से कुछ अन्य आदेशों के साथ बेहतर हल हो सकते थे।
JD लॉन्ग

1
मुझे लगता है कि मुझे लगा कि plyrफ़ंक्शंस के पीछे की अवधारणा फ़ंक्शंस के समान है *apply, इसलिए यदि आप एक कर सकते हैं, तो आप दूसरे को भी कर सकते हैं, लेकिन plyrफ़ंक्शंस को याद रखना आसान है। लेकिन मैं ddply()हथौड़ा पर पूरी तरह सहमत हूं !
जोफ्रवेल

1
प्लायर पैकेज में join()फ़ंक्शन होता है जो मर्ज के समान कार्य करता है। शायद यह प्लाई के संदर्भ में इसका उल्लेख करने के लिए अधिक है।
marbel

आइए हम गरीबों को न भूलें, भूल जाते हैंeapply
JDL

सामान्य रूप से शानदार जवाब, लेकिन मुझे लगता है कि यह और नीचे की उपयोगिता को कम करता vapplyहै sapply। इसका एक प्रमुख लाभ vapplyयह है कि यह आउटपुट प्रकार और लंबाई को लागू करता है, इसलिए आप सटीक आउटपुट या एक सूचनात्मक त्रुटि के साथ समाप्त हो जाएंगे। दूसरी ओर, sapplyउन नियमों का पालन करते हुए आउटपुट को सरल बनाने की कोशिश करेंगे जो हमेशा स्पष्ट नहीं होते हैं, और अन्यथा किसी सूची में वापस आते हैं। उदाहरण के लिए, उत्पादन के प्रकार के इस उत्पादन का अनुमान लगाने हेतु प्रयास करें: sapply(list(1:5, 6:10, matrix(1:4, 2)), function(x) head(x, 1))। किस बारे में sapply(list(matrix(1:4, 2), matrix(1:4, 2)), ...)?
एलेक्सी शिकलोमनोव

133

Http://www.slideshare.net/hadley/plyr-one-data-analytic-strategy की स्लाइड 21 से :

लागू, नीलम, lapply, द्वारा, कुल

(उम्मीद है कि यह स्पष्ट है कि applyसे मेल खाती है @ हैडली का aaplyऔर aggregateमेल खाती है करने के लिए @ हैडली के ddplyआदि एक ही SlideShare की स्लाइड 20 यदि आप इसे इस छवि से नहीं मिलता है स्पष्ट हो जाएगा।)

(बाईं ओर इनपुट है, शीर्ष पर आउटपुट है)


4
क्या स्लाइड में कोई टाइपो है? शीर्ष बाएं सेल aaply होना चाहिए
JHowIX

100

पहले जोरन के उत्कृष्ट उत्तर से शुरू करें - संदिग्ध कुछ भी बेहतर कर सकता है।

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

स्मृती-विज्ञान

  • lapplyएक सूची लागू होती है जो एक सूची या वेक्टर पर कार्य करती है और एक सूची लौटाती है।
  • sapplyएक साधारण lapply (जब संभव हो वेक्टर या मैट्रिक्स को वापस करने के लिए फ़ंक्शन डिफ़ॉल्ट)
  • vapplyएक सत्यापित आवेदन है (रिटर्न ऑब्जेक्ट प्रकार निर्धारित करने की अनुमति देता है)
  • rapplyनेस्टेड सूचियों के लिए एक पुनरावर्ती लागू होता है, अर्थात सूचियों के भीतर सूचियाँ
  • tapplyएक टैग लागू होता है जहां टैग सबसेट को पहचानते हैं
  • apply है सामान्य : एक मैट्रिक्स के पंक्तियों या स्तंभों को एक समारोह के लिए लागू होता है (या अधिक सामान्य रूप से एक सरणी के आयाम करने के लिए)

सही पृष्ठभूमि का निर्माण

यदि applyपरिवार का उपयोग करना अभी भी आपको थोड़ा अलग लगता है, तो यह हो सकता है कि आप एक महत्वपूर्ण दृष्टिकोण याद कर रहे हों।

ये दो लेख मदद कर सकते हैं। वे कार्यात्मक प्रोग्रामिंग तकनीकों को प्रेरित करने के लिए आवश्यक पृष्ठभूमि प्रदान करते हैं जो कार्यों के applyपरिवार द्वारा प्रदान की जा रही हैं ।

लिस्प के उपयोगकर्ता प्रतिमान को तुरंत पहचान लेंगे। यदि आप लिस्प से परिचित नहीं हैं, तो एक बार जब आप एफपी के चारों ओर अपना सिर प्राप्त करते हैं, तो आपको आर में उपयोग के लिए एक शक्तिशाली दृष्टिकोण प्राप्त applyहोगा - और भी बहुत कुछ समझ में आएगा।


51

चूँकि मुझे एहसास हुआ कि (बहुत ही उत्कृष्ट) इस पोस्ट के उत्तर में कमी byऔर aggregateस्पष्टीकरण हैं। यहाँ मेरा योगदान है।

द्वारा

byसमारोह, के रूप में दस्तावेज में कहा गया है, हालांकि हो सकता है, के लिए एक "आवरण" के रूप में tapplybyजब हम किसी ऐसे कार्य की गणना करना चाहते हैं जो tapplyसंभाल नहीं सकता है, तो शक्ति उत्पन्न होती है । एक उदाहरण यह कोड है:

ct <- tapply(iris$Sepal.Width , iris$Species , summary )
cb <- by(iris$Sepal.Width , iris$Species , summary )

 cb
iris$Species: setosa
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.300   3.200   3.400   3.428   3.675   4.400 
-------------------------------------------------------------- 
iris$Species: versicolor
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.000   2.525   2.800   2.770   3.000   3.400 
-------------------------------------------------------------- 
iris$Species: virginica
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.200   2.800   3.000   2.974   3.175   3.800 


ct
$setosa
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.300   3.200   3.400   3.428   3.675   4.400 

$versicolor
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.000   2.525   2.800   2.770   3.000   3.400 

$virginica
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.200   2.800   3.000   2.974   3.175   3.800 

अगर हम इन दो वस्तुओं प्रिंट, ctऔर cb, हम "अनिवार्य" एक ही परिणाम है और केवल मतभेद कि वे किस तरह दिखाया जाता है और विभिन्न में हैं classक्रमशः, विशेषताओं byके लिए cbऔर arrayके लिए ct

जैसा कि मैंने कहा है, byजब हम उपयोग नहीं कर सकते हैं तो उठती है tapply; निम्नलिखित कोड एक उदाहरण है:

 tapply(iris, iris$Species, summary )
Error in tapply(iris, iris$Species, summary) : 
  arguments must have same length

आर का कहना है कि तर्कों की लंबाई समान होनी चाहिए, "हम कारक के साथ-साथ summaryसभी चर की गणना करना चाहते हैं ": लेकिन आर बस ऐसा नहीं कर सकता क्योंकि यह नहीं जानता कि कैसे संभालना है।irisSpecies

byफ़ंक्शन के साथ आर data frameवर्ग के लिए एक विशिष्ट विधि भेजते हैं और फिर summaryफ़ंक्शन को काम करने देते हैं भले ही पहले तर्क की लंबाई (और प्रकार भी) अलग हो।

bywork <- by(iris, iris$Species, summary )

bywork
iris$Species: setosa
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.300   Min.   :2.300   Min.   :1.000   Min.   :0.100   setosa    :50  
 1st Qu.:4.800   1st Qu.:3.200   1st Qu.:1.400   1st Qu.:0.200   versicolor: 0  
 Median :5.000   Median :3.400   Median :1.500   Median :0.200   virginica : 0  
 Mean   :5.006   Mean   :3.428   Mean   :1.462   Mean   :0.246                  
 3rd Qu.:5.200   3rd Qu.:3.675   3rd Qu.:1.575   3rd Qu.:0.300                  
 Max.   :5.800   Max.   :4.400   Max.   :1.900   Max.   :0.600                  
-------------------------------------------------------------- 
iris$Species: versicolor
  Sepal.Length    Sepal.Width     Petal.Length   Petal.Width          Species  
 Min.   :4.900   Min.   :2.000   Min.   :3.00   Min.   :1.000   setosa    : 0  
 1st Qu.:5.600   1st Qu.:2.525   1st Qu.:4.00   1st Qu.:1.200   versicolor:50  
 Median :5.900   Median :2.800   Median :4.35   Median :1.300   virginica : 0  
 Mean   :5.936   Mean   :2.770   Mean   :4.26   Mean   :1.326                  
 3rd Qu.:6.300   3rd Qu.:3.000   3rd Qu.:4.60   3rd Qu.:1.500                  
 Max.   :7.000   Max.   :3.400   Max.   :5.10   Max.   :1.800                  
-------------------------------------------------------------- 
iris$Species: virginica
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.900   Min.   :2.200   Min.   :4.500   Min.   :1.400   setosa    : 0  
 1st Qu.:6.225   1st Qu.:2.800   1st Qu.:5.100   1st Qu.:1.800   versicolor: 0  
 Median :6.500   Median :3.000   Median :5.550   Median :2.000   virginica :50  
 Mean   :6.588   Mean   :2.974   Mean   :5.552   Mean   :2.026                  
 3rd Qu.:6.900   3rd Qu.:3.175   3rd Qu.:5.875   3rd Qu.:2.300                  
 Max.   :7.900   Max.   :3.800   Max.   :6.900   Max.   :2.500     

यह वास्तव में काम करता है और परिणाम बहुत आश्चर्यजनक है। यह वर्ग की एक ऐसी वस्तु है byजो Species(प्रत्येक के लिए) कहती है, summaryप्रत्येक चर की गणना करती है।

ध्यान दें कि यदि पहला तर्क एक है data frame, तो प्रेषण फ़ंक्शन में ऑब्जेक्ट के उस वर्ग के लिए एक विधि होनी चाहिए। उदाहरण के लिए, हम इस कोड का उपयोग उस meanफ़ंक्शन के साथ करेंगे जिसमें हमारा यह कोड होगा जिसका कोई अर्थ नहीं है:

 by(iris, iris$Species, mean)
iris$Species: setosa
[1] NA
------------------------------------------- 
iris$Species: versicolor
[1] NA
------------------------------------------- 
iris$Species: virginica
[1] NA
Warning messages:
1: In mean.default(data[x, , drop = FALSE], ...) :
  argument is not numeric or logical: returning NA
2: In mean.default(data[x, , drop = FALSE], ...) :
  argument is not numeric or logical: returning NA
3: In mean.default(data[x, , drop = FALSE], ...) :
  argument is not numeric or logical: returning NA

समग्र

aggregatetapplyअगर हम इसे इस तरह से इस्तेमाल करते हैं तो इसे एक और तरह के उपयोग के रूप में देखा जा सकता है ।

at <- tapply(iris$Sepal.Length , iris$Species , mean)
ag <- aggregate(iris$Sepal.Length , list(iris$Species), mean)

 at
    setosa versicolor  virginica 
     5.006      5.936      6.588 
 ag
     Group.1     x
1     setosa 5.006
2 versicolor 5.936
3  virginica 6.588

दो तत्काल मतभेद हैं कि का दूसरा तर्क aggregate चाहिए एक सूची हो, जबकि tapply कर सकते हैं (अनिवार्य नहीं) एक सूची हो सकता है और के उत्पादन में है कि aggregateएक डेटा फ्रेम है, जबकि में से एक tapplyएक है array

की शक्ति aggregateयह है कि यह आसानी से subsetतर्क के साथ डेटा के सबसेट को संभाल सकता है और यह tsवस्तुओं और formulaसाथ ही तरीकों के लिए है ।

ये तत्व कुछ स्थितियों में इसके aggregateसाथ काम करना आसान बनाते हैं tapply। यहाँ कुछ उदाहरण हैं (प्रलेखन में उपलब्ध):

ag <- aggregate(len ~ ., data = ToothGrowth, mean)

 ag
  supp dose   len
1   OJ  0.5 13.23
2   VC  0.5  7.98
3   OJ  1.0 22.70
4   VC  1.0 16.77
5   OJ  2.0 26.06
6   VC  2.0 26.14

हम इसे हासिल कर सकते हैं tapplyलेकिन वाक्य रचना थोड़ी कठिन है और आउटपुट (कुछ परिस्थितियों में) कम पठनीय है:

att <- tapply(ToothGrowth$len, list(ToothGrowth$dose, ToothGrowth$supp), mean)

 att
       OJ    VC
0.5 13.23  7.98
1   22.70 16.77
2   26.06 26.14

ऐसे समय होते हैं जब हम उपयोग नहीं कर सकते हैं byया tapplyहमें उपयोग करना पड़ता है aggregate

 ag1 <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, mean)

 ag1
  Month    Ozone     Temp
1     5 23.61538 66.73077
2     6 29.44444 78.22222
3     7 59.11538 83.88462
4     8 59.96154 83.96154
5     9 31.44828 76.89655

हम पिछले परिणाम को tapplyएक कॉल में प्राप्त नहीं कर सकते हैं, लेकिन हमें Monthप्रत्येक तत्वों के लिए माध्य की गणना करनी होगी और फिर उन्हें संयोजित करना होगा (यह भी ध्यान दें कि हमें कॉल करना होगा na.rm = TRUE, क्योंकि फ़ंक्शन के formulaतरीके aggregateडिफ़ॉल्ट रूप से हैं na.action = na.omit):

ta1 <- tapply(airquality$Ozone, airquality$Month, mean, na.rm = TRUE)
ta2 <- tapply(airquality$Temp, airquality$Month, mean, na.rm = TRUE)

 cbind(ta1, ta2)
       ta1      ta2
5 23.61538 65.54839
6 29.44444 79.10000
7 59.11538 83.90323
8 59.96154 83.96774
9 31.44828 76.90000

जब तक byहम सिर्फ यह नहीं प्राप्त कर सकते कि वास्तव में निम्न फ़ंक्शन कॉल में त्रुटि होती है (लेकिन सबसे अधिक संभावना यह आपूर्ति फ़ंक्शन से संबंधित है, mean)

by(airquality[c("Ozone", "Temp")], airquality$Month, mean, na.rm = TRUE)

अन्य बार परिणाम समान होते हैं और अंतर केवल कक्षा में होते हैं (और फिर इसे कैसे दिखाया / मुद्रित किया जाता है और न केवल - उदाहरण के लिए, इसे कैसे घटाया जाता है) वस्तु:

byagg <- by(airquality[c("Ozone", "Temp")], airquality$Month, summary)
aggagg <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, summary)

पिछला कोड समान लक्ष्य और परिणाम प्राप्त करता है, कुछ बिंदुओं पर जो उपकरण का उपयोग करना है वह सिर्फ व्यक्तिगत स्वाद और जरूरतों का मामला है; पिछली दो वस्तुओं की सबसे बड़ी ज़रूरतें हैं।


जैसा कि मैंने कहा है, की शक्ति तब उत्पन्न होती है जब हम टैपली का उपयोग नहीं कर सकते हैं; निम्नलिखित कोड एक उदाहरण है: यह आपके द्वारा उपयोग किए गए कार्य हैं। और आपने सारांश की गणना का एक उदाहरण दिया है। वैसे यह कहें कि सारांश आँकड़ों की गणना केवल यह की जा सकती है कि उसे सफाई की आवश्यकता होगी: उदाहरण के लिए data.frame(tapply(unlist(iris[,-5]),list(rep(iris[,5],ncol(iris[-5])),col(iris[-5])),summary))यह टप्पल . With the right splitting there is nothing you cant do with टप्पली . The only thing is it returns a matrix. Please be careful by saying we cant use टप्पली का उपयोग है
ओनाम्बु

35

बहुत सारे शानदार उत्तर हैं जो प्रत्येक फ़ंक्शन के उपयोग मामलों में अंतर पर चर्चा करते हैं। जवाब में से कोई भी प्रदर्शन में अंतर पर चर्चा नहीं करता है। यह उचित है क्योंकि विभिन्न कार्य विभिन्न इनपुट की अपेक्षा करते हैं और विभिन्न आउटपुट का उत्पादन करते हैं, फिर भी उनमें से अधिकांश श्रृंखला / समूहों द्वारा मूल्यांकन करने का एक सामान्य सामान्य उद्देश्य है। मेरा जवाब प्रदर्शन पर ध्यान केंद्रित करने वाला है। वैक्टर से ऊपर इनपुट निर्माण के कारण समय में शामिल किया गया है, यह भी applyफ़ंक्शन मापा नहीं है।

मैंने दो अलग-अलग कार्यों का परीक्षण किया है sumऔर lengthएक ही बार में। परीक्षण की गई मात्रा इनपुट पर 50M और आउटपुट पर 50K है। मैंने वर्तमान में दो लोकप्रिय पैकेजों को भी शामिल किया है जो उस समय व्यापक रूप से उपयोग नहीं किए गए थे जब प्रश्न पूछा गया था, data.tableऔर dplyr। दोनों निश्चित रूप से देखने लायक हैं कि क्या आप अच्छे प्रदर्शन का लक्ष्य बना रहे हैं।

library(dplyr)
library(data.table)
set.seed(123)
n = 5e7
k = 5e5
x = runif(n)
grp = sample(k, n, TRUE)

timing = list()

# sapply
timing[["sapply"]] = system.time({
    lt = split(x, grp)
    r.sapply = sapply(lt, function(x) list(sum(x), length(x)), simplify = FALSE)
})

# lapply
timing[["lapply"]] = system.time({
    lt = split(x, grp)
    r.lapply = lapply(lt, function(x) list(sum(x), length(x)))
})

# tapply
timing[["tapply"]] = system.time(
    r.tapply <- tapply(x, list(grp), function(x) list(sum(x), length(x)))
)

# by
timing[["by"]] = system.time(
    r.by <- by(x, list(grp), function(x) list(sum(x), length(x)), simplify = FALSE)
)

# aggregate
timing[["aggregate"]] = system.time(
    r.aggregate <- aggregate(x, list(grp), function(x) list(sum(x), length(x)), simplify = FALSE)
)

# dplyr
timing[["dplyr"]] = system.time({
    df = data_frame(x, grp)
    r.dplyr = summarise(group_by(df, grp), sum(x), n())
})

# data.table
timing[["data.table"]] = system.time({
    dt = setnames(setDT(list(x, grp)), c("x","grp"))
    r.data.table = dt[, .(sum(x), .N), grp]
})

# all output size match to group count
sapply(list(sapply=r.sapply, lapply=r.lapply, tapply=r.tapply, by=r.by, aggregate=r.aggregate, dplyr=r.dplyr, data.table=r.data.table), 
       function(x) (if(is.data.frame(x)) nrow else length)(x)==k)
#    sapply     lapply     tapply         by  aggregate      dplyr data.table 
#      TRUE       TRUE       TRUE       TRUE       TRUE       TRUE       TRUE 

# print timings
as.data.table(sapply(timing, `[[`, "elapsed"), keep.rownames = TRUE
              )[,.(fun = V1, elapsed = V2)
                ][order(-elapsed)]
#          fun elapsed
#1:  aggregate 109.139
#2:         by  25.738
#3:      dplyr  18.978
#4:     tapply  17.006
#5:     lapply  11.524
#6:     sapply  11.326
#7: data.table   2.686

क्या यह सामान्य है कि सपने देखने वाले कार्यों की तुलना में कम है?
मुस्तफा

1
@DimitriPetrenko मुझे ऐसा नहीं लगता, यकीन नहीं होता कि यह यहाँ क्यों है। अपने स्वयं के डेटा के खिलाफ परीक्षण करना सबसे अच्छा है, क्योंकि कई कारक हैं जो खेल में आते हैं।
जंगोरकी

28

यहां सभी शानदार उत्तरों के बावजूद, 2 और आधार कार्य हैं जो उल्लेख के योग्य हैं, उपयोगी outerफ़ंक्शन और अस्पष्ट eapplyफ़ंक्शन

बाहरी

outerएक बहुत उपयोगी एक अधिक सांसारिक के रूप में छिपा हुआ है। यदि आप outerइसके वर्णन के लिए सहायता पढ़ते हैं तो कहते हैं:

The outer product of the arrays X and Y is the array A with dimension  
c(dim(X), dim(Y)) where element A[c(arrayindex.x, arrayindex.y)] =   
FUN(X[arrayindex.x], Y[arrayindex.y], ...).

जिससे यह प्रतीत होता है कि यह केवल रैखिक बीजगणित प्रकार की चीजों के लिए उपयोगी है। हालांकि, यह बहुत इस्तेमाल किया जा सकता है जैसे mapplyइनपुट के दो वैक्टर में एक फ़ंक्शन लागू करना। अंतर यह है कि mapplyफ़ंक्शन को पहले दो तत्वों पर और फिर दूसरे दो आदि पर outerलागू किया जाएगा , जबकि फ़ंक्शन को पहले वेक्टर से एक तत्व के प्रत्येक संयोजन और दूसरे से एक पर लागू होगा। उदाहरण के लिए:

 A<-c(1,3,5,7,9)
 B<-c(0,3,6,9,12)

mapply(FUN=pmax, A, B)

> mapply(FUN=pmax, A, B)
[1]  1  3  6  9 12

outer(A,B, pmax)

 > outer(A,B, pmax)
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    3    6    9   12
 [2,]    3    3    6    9   12
 [3,]    5    5    6    9   12
 [4,]    7    7    7    9   12
 [5,]    9    9    9    9   12

मैंने व्यक्तिगत रूप से इसका उपयोग किया है जब मेरे पास मूल्यों का एक वेक्टर और शर्तों का एक वेक्टर है और यह देखने की इच्छा है कि कौन से मूल्य किन शर्तों को पूरा करते हैं।

eapply

eapplyकी तरह है lapply, सिवाय इसके कि बजाय एक सूची में प्रत्येक तत्व के एक समारोह को लागू करने से, यह एक समारोह हर तत्व के लिए एक वातावरण में लागू होता है। उदाहरण के लिए, यदि आप वैश्विक वातावरण में उपयोगकर्ता परिभाषित कार्यों की सूची खोजना चाहते हैं:

A<-c(1,3,5,7,9)
B<-c(0,3,6,9,12)
C<-list(x=1, y=2)
D<-function(x){x+1}

> eapply(.GlobalEnv, is.function)
$A
[1] FALSE

$B
[1] FALSE

$C
[1] FALSE

$D
[1] TRUE 

सच कहूँ तो मैं इसका बहुत उपयोग नहीं करता लेकिन अगर आप बहुत सारे पैकेज बना रहे हैं या बहुत सारे वातावरण बना रहे हैं तो यह आपके काम आ सकता है।


25

शायद यह ध्यान देने योग्य है aveaveके tapplyमित्र के चचेरे भाई हैं। यह एक परिणाम के रूप में देता है जिसे आप सीधे अपने डेटा फ़्रेम में प्लग कर सकते हैं।

dfr <- data.frame(a=1:20, f=rep(LETTERS[1:5], each=4))
means <- tapply(dfr$a, dfr$f, mean)
##  A    B    C    D    E 
## 2.5  6.5 10.5 14.5 18.5 

## great, but putting it back in the data frame is another line:

dfr$m <- means[dfr$f]

dfr$m2 <- ave(dfr$a, dfr$f, FUN=mean) # NB argument name FUN is needed!
dfr
##   a f    m   m2
##   1 A  2.5  2.5
##   2 A  2.5  2.5
##   3 A  2.5  2.5
##   4 A  2.5  2.5
##   5 B  6.5  6.5
##   6 B  6.5  6.5
##   7 B  6.5  6.5
##   ...

आधार पैकेज में ऐसा कुछ भी नहीं है जो aveपूरे डेटा फ़्रेम के लिए काम करता है (जैसा byकि tapplyडेटा फ़्रेम के लिए है)। लेकिन आप इसे ठग सकते हैं:

dfr$foo <- ave(1:nrow(dfr), dfr$f, FUN=function(x) {
    x <- dfr[x,]
    sum(x$m*x$m2)
})
dfr
##     a f    m   m2    foo
## 1   1 A  2.5  2.5    25
## 2   2 A  2.5  2.5    25
## 3   3 A  2.5  2.5    25
## ...

12

मैंने हाल ही में उपयोगी sweepकार्य की खोज की और इसे पूर्णता के लिए यहाँ जोड़ा:

झाड़ू लगा दो

मूल विचार एक सरणी पंक्ति- या कॉलम-वार के माध्यम से स्वीप करना और एक संशोधित सरणी वापस करना है। एक उदाहरण यह स्पष्ट कर देगा (स्रोत: डेटाकैम्प ):

मान लें कि आपके पास एक मैट्रिक्स है और इसे कॉलम-वार मानकीकृत करना चाहते हैं :

dataPoints <- matrix(4:15, nrow = 4)

# Find means per column with `apply()`
dataPoints_means <- apply(dataPoints, 2, mean)

# Find standard deviation with `apply()`
dataPoints_sdev <- apply(dataPoints, 2, sd)

# Center the points 
dataPoints_Trans1 <- sweep(dataPoints, 2, dataPoints_means,"-")
print(dataPoints_Trans1)
##      [,1] [,2] [,3]
## [1,] -1.5 -1.5 -1.5
## [2,] -0.5 -0.5 -0.5
## [3,]  0.5  0.5  0.5
## [4,]  1.5  1.5  1.5
# Return the result
dataPoints_Trans1
##      [,1] [,2] [,3]
## [1,] -1.5 -1.5 -1.5
## [2,] -0.5 -0.5 -0.5
## [3,]  0.5  0.5  0.5
## [4,]  1.5  1.5  1.5
# Normalize
dataPoints_Trans2 <- sweep(dataPoints_Trans1, 2, dataPoints_sdev, "/")

# Return the result
dataPoints_Trans2
##            [,1]       [,2]       [,3]
## [1,] -1.1618950 -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983 -0.3872983
## [3,]  0.3872983  0.3872983  0.3872983
## [4,]  1.1618950  1.1618950  1.1618950

एनबी: इस सरल उदाहरण के लिए एक ही परिणाम बेशक अधिक आसानी से प्राप्त किया जा सकता है
apply(dataPoints, 2, scale)


1
क्या यह समूहीकरण से संबंधित है?
फ्रैंक

2
@Frank: ठीक है, आपके साथ ईमानदार होने के लिए इस पोस्ट का शीर्षक भ्रामक है: जब आप स्वयं प्रश्न पढ़ते हैं तो यह "लागू परिवार" के बारे में होता है। sweepएक उच्च-क्रम का कार्य है, जैसे कि यहां उल्लेखित अन्य सभी, उदाहरण applyके लिए sapply, lapplyइसलिए एक ही प्रश्न 1,000 उत्थान और उसमें दिए गए उदाहरणों के साथ स्वीकृत उत्तर के बारे में पूछा जा सकता है। बस applyवहाँ के लिए दिए गए उदाहरण पर एक नज़र है ।
वॉनजड

2
स्वीप में एक भ्रामक नाम है, भ्रामक चूक और भ्रामक पैरामीटर नाम :)। मेरे लिए इसे इस तरह समझना आसान है: 1) STATS वेक्टर या एकल मान है जिसे पहले इनपुट के समान आकार के मैट्रिक्स बनाने के लिए दोहराया जाएगा, 2) FUN को 1 इनपुट और इस नए मैट्रिक्स पर लागू किया जाएगा। हो सकता है कि बेहतर द्वारा सचित्र: sweep(matrix(1:6,nrow=2),2,7:9,list)। यह आमतौर पर अधिक कुशल है applyक्योंकि जहां applyलूप होते हैं, sweepवे वेक्टरकृत कार्यों का उपयोग करने में सक्षम हैं।
मूडी_मुद्सकीपर

2

सीआरएएन पर हाल ही में जारी किए गए पतन पैकेज में, मैंने केवल 2 कार्यों में अधिकांश सामान्य लागू कार्यक्षमता को संपीड़ित करने का प्रयास किया है:

  1. dapply(डेटा-अप्लाई) मैट्रिस और डेटा.फ्रेम की पंक्तियों या (डिफ़ॉल्ट) कॉलमों पर फ़ंक्शंस लागू करता है और (डिफ़ॉल्ट) एक ही प्रकार की एक ही वस्तु और एक ही विशेषता के साथ रिटर्न देता है (जब तक कि प्रत्येक गणना का परिणाम परमाणु न हो और drop = TRUE)। प्रदर्शन lapplyडेटा.फ्रेम स्तंभों के लिए, और applyमैट्रिक्स पंक्तियों या स्तंभों की तुलना में लगभग 2x अधिक तेज़ होता है । समानांतरवाद mclapply(केवल मैक के लिए) के माध्यम से उपलब्ध है ।

वाक्य - विन्यास:

dapply(X, FUN, ..., MARGIN = 2, parallel = FALSE, mc.cores = 1L, 
       return = c("same", "matrix", "data.frame"), drop = TRUE)

उदाहरण:

# Apply to columns:
dapply(mtcars, log)
dapply(mtcars, sum)
dapply(mtcars, quantile)
# Apply to rows:
dapply(mtcars, sum, MARGIN = 1)
dapply(mtcars, quantile, MARGIN = 1)
# Return as matrix:
dapply(mtcars, quantile, return = "matrix")
dapply(mtcars, quantile, MARGIN = 1, return = "matrix")
# Same for matrices ...
  1. BYसदिश, मैट्रिक्स और data.frame विधि के साथ विभाजन-लागू-गठबंधन कंप्यूटिंग के लिए एक S3 जेनेरिक है। यह की तुलना में काफी तेज है tapply, byऔर aggregate( plyrबड़े डेटा पर भी तेजी से dplyrहालांकि तेज है)।

वाक्य - विन्यास:

BY(X, g, FUN, ..., use.g.names = TRUE, sort = TRUE,
   expand.wide = FALSE, parallel = FALSE, mc.cores = 1L,
   return = c("same", "matrix", "data.frame", "list"))

उदाहरण:

# Vectors:
BY(iris$Sepal.Length, iris$Species, sum)
BY(iris$Sepal.Length, iris$Species, quantile)
BY(iris$Sepal.Length, iris$Species, quantile, expand.wide = TRUE) # This returns a matrix 
# Data.frames
BY(iris[-5], iris$Species, sum)
BY(iris[-5], iris$Species, quantile)
BY(iris[-5], iris$Species, quantile, expand.wide = TRUE) # This returns a wider data.frame
BY(iris[-5], iris$Species, quantile, return = "matrix") # This returns a matrix
# Same for matrices ...

समूहीकरण चर की सूची भी आपूर्ति की जा सकती है g

प्रदर्शन के बारे में बात करना: पतन का एक मुख्य लक्ष्य आर में उच्च-प्रदर्शन प्रोग्रामिंग को बढ़ावा देना और पूरी तरह से विभाजन-लागू-गठबंधन से आगे बढ़ना है। इस प्रयोजन के लिए पैकेज सी का एक पूरा सेट ++ आधारित तेजी से सामान्य कार्य हैं: fmean, fmedian, fmode, fsum, fprod, fsd, fvar, fmin, fmax, ffirst, flast, fNobs, fNdistinct, fscale, fbetween, fwithin, fHDbetween, fHDwithin, flag, fdiffऔर fgrowth। वे डेटा के माध्यम से एक ही पास में समूहीकृत गणना करते हैं (अर्थात कोई विभाजन और पुनर्संस्थापन नहीं)।

वाक्य - विन्यास:

fFUN(x, g = NULL, [w = NULL,] TRA = NULL, [na.rm = TRUE,] use.g.names = TRUE, drop = TRUE)

उदाहरण:

v <- iris$Sepal.Length
f <- iris$Species

# Vectors
fmean(v)             # mean
fmean(v, f)          # grouped mean
fsd(v, f)            # grouped standard deviation
fsd(v, f, TRA = "/") # grouped scaling
fscale(v, f)         # grouped standardizing (scaling and centering)
fwithin(v, f)        # grouped demeaning

w <- abs(rnorm(nrow(iris)))
fmean(v, w = w)      # Weighted mean
fmean(v, f, w)       # Weighted grouped mean
fsd(v, f, w)         # Weighted grouped standard-deviation
fsd(v, f, w, "/")    # Weighted grouped scaling
fscale(v, f, w)      # Weighted grouped standardizing
fwithin(v, f, w)     # Weighted grouped demeaning

# Same using data.frames...
fmean(iris[-5], f)                # grouped mean
fscale(iris[-5], f)               # grouped standardizing
fwithin(iris[-5], f)              # grouped demeaning

# Same with matrices ...

पैकेज विगनेट्स में मैं बेंचमार्क प्रदान करता हूं। तेजी से कार्यों के साथ प्रोग्रामिंग, dplyr या data.table के साथ प्रोग्रामिंग की तुलना में काफी तेज है , विशेष रूप से छोटे डेटा पर, लेकिन बड़े डेटा पर भी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.