2012-03-26 18 views
5

उद्देश्य डेटा फ्रेम में एक कारक/स्ट्रिंग चर के लिए संकेतक बनाना है। उस डेटाफ्रेम में> 2 मिमी पंक्तियां हैं, और विंडोज़ पर आर चल रही हैं, मेरे पास pparr का उपयोग करने का विकल्प नहीं है .parallel = T। तो मैं प्लीयर और reshape2 के साथ "विभाजन और जीत" मार्ग ले रहा हूँ।बड़े डेटा फ्रेम में संकेतक उत्पन्न करना

स्मृति से बाहर पिघल और कलाकारों रन चल रहा है, और

ddply(idata.frame(items) , c("ID") , function(x){ 
     ( colSums(model.matrix(~ x$element - 1)) > 0 ) 
} , .progress="text")  

या

ddply(idata.frame(items) , c("ID") , function(x){ 
      ( elements %in% x$element ) 
    } , .progress="text") 

का उपयोग कर कुछ समय ले करता है। सबसे तेज़ दृष्टिकोण नीचे कॉल करने के लिए कॉल है। क्या आप इसे गति देने का एक तरीका देखते हैं? % कथन में% model.matrix कॉल से तेज़ी से चलता है। धन्यवाद।

set.seed(123) 

dd <- data.frame(
    id = sample(1:5, size=10 , replace=T) , 
    prd = letters[sample(1:5, size=10 , replace=T)] 
) 

prds <- unique(dd$prd) 

tapply(dd$prd , dd$id , function(x) prds %in% x) 
+0

मैं आपके उदाहरण से उलझन में हूं। आप 'dd $ prd' को' dd $ id' से विभाजित कर रहे हैं, फिर पूछें कि प्रत्येक आईडी में 'prds' के कौन से मान दर्शाए जाते हैं - लेकिन' prds' को क्रमबद्ध नहीं किया जाता है (!) क्या आप 'prds <- sort (अद्वितीय (डीडी $ पीआरडी)) '(जो मुझे और अधिक समझ में आता है ...)? –

+0

जब तक पीआरडी में उपलब्ध तत्वों के अनुरूप संकेतक (लॉजिकल) आईडी में एक ही ऑर्डर करते हैं, इससे कोई फ़र्क नहीं पड़ता कि उन्हें कैसे क्रमबद्ध किया जाता है। –

+0

ठीक है। मेरे अन्य प्रश्न को नीचे दिए गए मेरे उत्तर में देखें ... –

उत्तर

4

इस समस्या के लिए, संकुल bigmemory और bigtabulate। यहाँ एक से थोड़ा अधिक महत्वाकांक्षी उदाहरण है:

library(bigmemory) 
library(bigtabulate) 

set.seed(123) 

dd <- data.frame(
    id = sample(1:15, size=2e6 , replace=T), 
    prd = letters[sample(1:15, size=2e6 , replace=T)] 
) 

prds <- unique(dd$prd) 

benchmark(
bigtable(dd,c(1,2))>0, 
table(dd[,1],dd[,2])>0, 
xtabs(~id+prd,data=dd)>0, 
tapply(dd$prd , dd$id , function(x) prds %in% x) 
) 

और बेंच मार्किंग के परिणाम (मैं नई बातें हर समय सीख रहा हूँ):

          test replications elapsed relative user.self sys.self user.child sys.child 
1      bigtable(dd, c(1, 2)) > 0   100 54.401 1.000000 51.759 3.817   0   0 
2     table(dd[, 1], dd[, 2]) > 0   100 112.361 2.065422 107.526 6.614   0   0 
4 tapply(dd$prd, dd$id, function(x) prds %in% x)   100 178.308 3.277660 166.544 13.275   0   0 
3    xtabs(~id + prd, data = dd) > 0   100 229.435 4.217478 217.014 16.660   0   0 

और वह एक पर्याप्त राशि से बाहर जीतने bigtable को दर्शाता है। परिणाम बहुत अधिक हैं कि सभी prds सभी आईडी में हैं, लेकिन परिणामों के प्रारूप के विवरण के लिए ?bigtable देखें।

+0

बहुत बहुत धन्यवाद। –

+0

वास्तविक डेटासेट (!) पर रन अभी पूरा हो गया है (bigtable का उपयोग कर)। –

1

%in% फ़ंक्शन का उपयोग मेरे पीछे की ओर लगता है। और यदि आप डेटा की प्रत्येक पंक्ति के लिए एक वास्तविक/गलत परिणाम चाहते हैं तो आपको वेक्टर ऑपरेशन या ave के रूप में% में% का उपयोग करना चाहिए। यद्यपि इसकी आवश्यकता नहीं है, लेकिन यदि आप एक अधिक जटिल कार्य थे जो प्रत्येक आइटम पर लागू होने की आवश्यकता होती है तो आप इसका उपयोग करना चाहेंगे।

set.seed(123) 

dd <- data.frame(
    id = sample(1:5, size=10 , replace=T) , 
    prd = letters[sample(1:5, size=10 , replace=T)] 
) 

prds <- unique(dd$prd) 
target.prds <- prds[1:2] 
dd$prd.in.trgt <- with(dd, prd %in% target.prds) 
+0

'prds' (या 'target.prds') के रूप में कई संकेतक होंगे:% c (1) में' c (1,2,3)% 'इंगित करेगा कि 1 उस रिकॉर्ड में है, लेकिन न तो 2 न ही 3. –

+0

आप कुछ ऐसा होने के लिए% में% को फिर से परिभाषित नहीं कर सकते हैं। और डेटाफ्रेम को सभी तत्वों की प्रति पंक्ति नियमित प्रविष्टियों की आवश्यकता होती है। आपको एक डेटा संरचना का उपयोग करने की आवश्यकता है जो "हिट", या तो TRUEs और FALSEs या किसी सूची का लॉजिकल मैट्रिक्स है। –

+0

यकीन नहीं है कि मैं समझ रहा हूं कि आप क्या कह रहे हैं। '% में '%' की कॉल हमेशा तार्किक संख्याओं को वापस कर देगी। मैंने 'tapply' कॉल में' function (x) अद्वितीय (x $ prd) 'के साथ शुरू किया, और यह एक रैगर्ड सरणी उत्पन्न करता। –

2

आप थोड़ा और अधिक कह सकते हैं कि समस्या को स्तरों के नंबर, आईडी, आदि (की संख्या की दृष्टि से बड़े पैमाने अगर आप पर्याप्त व्यक्तियों सूचक मैट्रिक्स आप के लिए तो स्तरों की संख्या, तय रहेंगे 'कंप्यूटिंग सभी TRUE/सभी 1 तक पहुंच जाएगी ...)? मैं उम्मीद है कि xtabs तेजी से हो सकता है, लेकिन यह अपने मित्रों को हो सकता है इस आकार के एक उदाहरण के लिए नहीं है ...

library(rbenchmark) 
benchmark(
      tapply(dd$prd , dd$id , function(x) prds %in% x), 
      xtabs(~id+prd,data=dd)>0) 

    test  replications elapsed relative 
1 tapply(...)    100 0.053 1.000000 
2 xtabs(...) > 0   100 0.120 2.264151 
+0

13.5 मिलियन आइटम हैं (780,000 आईडी में, इसलिए प्रति आईडी एकाधिक आइटम)।पीआरडी में 83 विभिन्न तत्व हैं। रास्ते में rbenchmark पर मेरा ध्यान आकर्षित करने के लिए धन्यवाद। –

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