2013-01-21 21 views
10

से अप्रत्याशित आउटपुट aggregate के साथ अन्य प्रश्न here के लिए प्रयोग करते समय, मुझे एक अजीब परिणाम का सामना करना पड़ा। मैं यह समझने में असमर्थ हूं कि मैं क्या कर रहा हूं और सोच रहा हूं कि मैं जो कर रहा हूं वह पूरी तरह गलत है।कुल

df <- structure(list(V1 = c(1L, 2L, 1L, 2L, 3L, 1L), 
        V2 = c(2L, 3L, 2L, 3L, 4L, 2L), 
        V3 = c(3L, 4L, 3L, 4L, 5L, 3L), 
        V4 = c(4L, 5L, 4L, 5L, 6L, 4L)), 
        .Names = c("V1", "V2", "V3", "V4"), 
     row.names = c(NA, -6L), class = "data.frame") 
> df 
# V1 V2 V3 V4 
# 1 1 2 3 4 
# 2 2 3 4 5 
# 3 1 2 3 4 
# 4 2 3 4 5 
# 5 3 4 5 6 
# 6 1 2 3 4 

अब, अगर मैं df में उनकी आवृत्ति का संकेत एक data.frameके साथ एक अतिरिक्त स्तंभ के साथ अद्वितीय पंक्तियां उत्पादन करना चाहते हैं:

मान लीजिए, मैं एक data.frame इस तरह की है। इस उदाहरण के लिए,

# V1 V2 V3 V4 x 
# 1 1 2 3 4 3 
# 2 2 3 4 5 2 
# 3 3 4 5 6 1 

मैं इस प्रकार प्रयोग करके इस उत्पादन aggregate का उपयोग कर प्राप्त:

> aggregate(do.call(paste, df), by=df, print) 

# [1] "1 2 3 4" "1 2 3 4" "1 2 3 4" 
# [1] "2 3 4 5" "2 3 4 5" 
# [1] "3 4 5 6" 
# V1 V2 V3 V4       x 
# 1 1 2 3 4 1 2 3 4, 1 2 3 4, 1 2 3 4 
# 2 2 3 4 5   2 3 4 5, 2 3 4 5 
# 3 3 4 5 6     3 4 5 6 

तो, यह मुझे चिपकाया स्ट्रिंग दे दी है। इसलिए, अगर मैं print के बजाय length का उपयोग करना चाहता था, तो मुझे मुझे ऐसी घटनाओं की संख्या देनी चाहिए, जो वांछित परिणाम है, जो मामला था (जैसा कि नीचे दिखाया गया है)।

> aggregate(do.call(paste, df), by=df, length) 
# V1 V2 V3 V4 x 
# 1 1 2 3 4 3 
# 2 2 3 4 5 2 
# 3 3 4 5 6 1 

और यह काम करने लग रहा था। हालांकि, जब data.frame आयाम 4 * 2500 हैं, आउटपुट data.frame 4 * 2501 के बजाय 1 * 2501 है (सभी पंक्तियां अद्वितीय हैं, इसलिए आवृत्ति 1 है)।

> df <- as.data.frame(matrix(sample(1:3, 1e4, replace = TRUE), nrow=4)) 
> o <- aggregate(do.call(paste, df), by=df, length) 
> dim(o) 
# [1] 1 2501 

मैं सिर्फ अद्वितीय पंक्तियों के साथ छोटे data.frames के साथ परीक्षण किया है और यह सही निर्गम (परिवर्तन nrow=40, उदाहरण के लिए) देता है। हालांकि, जब मैट्रिक्स के आयाम बढ़ते हैं, तो यह काम नहीं कर रहा है। और मैं सिर्फ यह नहीं समझ सकता कि क्या गलत हो रहा है! कोई विचार?

+2

शायद, क्योंकि तार बहुत लंबा हो जाते हैं और 'as.character' लाइनब्रेक्स डालें? – Roland

+0

हां, एक विकल्प के रूप में आप 'कुल (प्रतिनिधि (1, निरो (डीएफ)), डीएफ, फन = लंबाई) कर सकते हैं। – flodel

+1

यह 'as.character()' के साथ कुछ भी नहीं है क्योंकि इसके प्रत्येक तर्क एक लंबाई 1 वेक्टर है। यह देखने के लिए कि यह भाग काम करता है, बस 'do.call (पेस्ट, डीएफ [1: 3,])' करें। –

उत्तर

10

यहां मुद्दा यह है कि aggregate.data.frame() समूह निर्धारित करता है।

aggregate.data.frame() में एक लूप है जो समूहिंग चर grp बनाता है। कि पाश में, grp बदल दिया जाता है/के माध्यम से अद्यतन:

grp <- grp * nlevels(ind) + (as.integer(ind) - 1L) 

समस्या अपने उदाहरण के साथ करता है, तो है कि एक बार by कारकों में बदल जाती है, और पाश अपने उदाहरण में इन सभी कारकों के से अधिक चला गया है, grp समाप्त होता है ऊपर जा रहा है:

Browse[2]> grp 
[1] Inf Inf Inf Inf 

अनिवार्य रूप से पाशन अद्यतन एक नंबर Inf से पृथक करने के लिए grp के मूल्यों धक्का दे दिया।

कि, aggregate.data.frame() बाद में इस

y <- y[match(sort(unique(grp)), grp, 0L), , drop = FALSE] 

करता किया करने के बाद और यहां पहले समस्या अब के रूप में

क्योंकि

dim(y[match(sort(unique(grp)), grp, 0L), , drop = FALSE]) 

match(sort(unique(grp)), grp, 0L) 

स्पष्ट रूप से सिर्फ रिटर्न 1 में प्रकट होता है:

> match(sort(unique(grp)), grp, 0L) 
[1] 1 

क्योंकि grp का केवल एक अद्वितीय मूल्य है।

+1

'द्वारा' द्वारा बनाए गए बहुत से समूह हैं। मैं आपको यह करने की अनुशंसा नहीं करता हूं लेकिन इस मुद्दे को देखने का एक और तरीका है उप-डेटा फ्रेम बनाना जो उस पर काम करेगा, 'जीआरपी' 'इन्फ' पर नहीं गया: 'लंबाई (विभाजन (do.call (पेस्ट, डीएफ), डीएफ)) '। ** चेतावनी ** जो कुछ आपकी सभी रैम का उपभोग करेंगे (मेरे 4 जीबी लैपटॉप पर मैं तेजी से स्वैप स्पेस को थ्रैश कर रहा था)। –

+1

@ अरुण हाँ, 'डीबगोनस()' इस तरह की चीज़ के लिए आपका मित्र है। –

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