2011-08-29 12 views
8

मैं अपने डेटा, कंपाउंड, दोहराने और मास के आधार पर वर्गीकृत संक्षेप में प्रस्तुत करने के लिए निम्न कोड का उपयोग करें।सॉर्टिंग के बिना ddply() कैसे करें?

summaryDataFrame <- ddply(reviewDataFrame, .(Compound, Replicate, Mass), 
    .fun = calculate_T60_Over_T0_Ratio) 

एक दुर्भाग्यपूर्ण पक्ष प्रभाव है कि परिणामी डेटा फ्रेम उन क्षेत्रों के अनुसार क्रमबद्ध किया जाता है। मैं ऐसा करना चाहता हूं और मूल डेटा फ्रेम के समान क्रम में कंपाउंड, प्रतिलिपि और मास रखना चाहता हूं। कोई विचार? मैंने मूल डेटा के अनुक्रमिक पूर्णांक के "सॉर्टिंग" कॉलम को जोड़ने का प्रयास किया, लेकिन निश्चित रूप से मैं इसे .variables में शामिल नहीं कर सकता क्योंकि मैं इसे 'समूह' नहीं करना चाहता, और इसलिए यह वापस नहीं किया गया है summaryDataFrame।

सहायता के लिए धन्यवाद।

+0

इसमें 'write.table' के साथ कुछ लेना देना नहीं है; शीर्षक बदला जाना चाहिए। –

उत्तर

11

यह plyr मेलिंग सूची एक पर आया समय पहले (कम नहीं @kohske द्वारा उठाए गए) और यह एक समाधान सीमित मामलों के लिए पीटर Meilstrup द्वारा की पेशकश की है:

#Peter's version used a function gensym to 
# create the col name, but I couldn't track down 
# what package it was in. 
keeping.order <- function(data, fn, ...) { 
    col <- ".sortColumn" 
    data[,col] <- 1:nrow(data) 
    out <- fn(data, ...) 
    if (!col %in% colnames(out)) stop("Ordering column not preserved by function") 
    out <- out[order(out[,col]),] 
    out[,col] <- NULL 
    out 
} 

#Some sample data 
d <- structure(list(g = c(2L, 2L, 1L, 1L, 2L, 2L), v = c(-1.90127112738315, 
-1.20862680183042, -1.13913266070505, 0.14899803094742, -0.69427656843677, 
0.872558638137971)), .Names = c("g", "v"), row.names = c(NA, 
-6L), class = "data.frame") 

#This one resorts 
ddply(d, .(g), mutate, v=scale(v)) #does not preserve order of d 

#This one does not 
keeping.order(d, ddply, .(g), mutate, v=scale(v)) #preserves order of d 

कृपया हैडली के लिए thread पढ़ा करते हैं इस कार्यक्षमता को ddply में रोल करने के लिए पर्याप्त सामान्य क्यों नहीं हो सकता है, विशेष रूप से यह संभवतः आपके मामले में लागू होता है क्योंकि आप प्रत्येक टुकड़े के साथ कम पंक्तियों को वापस करने की संभावना रखते हैं।

संपादित अधिक सामान्य मामलों

ddply कुछ है कि एक आदेश आप पसंद नहीं करते में क्रमबद्ध हो जाता outputting है तो के लिए एक रणनीति शामिल करने के लिए आप मूल रूप से दो विकल्प हैं: बंटवारे चर पर वांछित आदेश निर्दिष्ट पहले से उपयोग करते हुए आदेश दिया गया कारक, या तथ्य के बाद आउटपुट मैन्युअल रूप से सॉर्ट करें। , तार का उपयोग कर अब के लिए

d <- data.frame(x1 = rep(letters[1:3],each = 5), 
       x2 = rep(letters[4:6],5), 
       x3 = 1:15,stringsAsFactors = FALSE) 

:

उदाहरण के लिए, निम्न डेटा देखें। ddply उत्पादन, जो इस मामले में डिफ़ॉल्ट शाब्दिक आदेश आवश्यक होगा सॉर्ट देगा:

> ddply(d,.(x1,x2),summarise, val = sum(x3)) 
    x1 x2 val 
1 a d 5 
2 a e 7 
3 a f 3 
4 b d 17 
5 b e 8 
6 b f 15 
7 c d 13 
8 c e 25 
9 c f 27 


> ddply(d[sample(1:15,15),],.(x1,x2),summarise, val = sum(x3)) 
    x1 x2 val 
1 a d 5 
2 a e 7 
3 a f 3 
4 b d 17 
5 b e 8 
6 b f 15 
7 c d 13 
8 c e 25 
9 c f 27 

परिणामी डेटा फ्रेम "सही" आदेश में समाप्त नहीं किया जाता है, यह शायद इसलिए है क्योंकि आप वास्तव में उन में से कुछ चाहते हैं कारकों का आदेश दिया जा सकता है चर। मान लीजिए हम वास्तव में चाहते थे कि x1 और x2 तो तरह का आदेश दिया:

> ddply(d,.(x1,x2),summarise, val = sum(x3)) 
    x1 x2 val 
1 b d 17 
2 b f 15 
3 b e 8 
4 a d 5 
5 a f 3 
6 a e 7 
7 c d 13 
8 c f 27 
9 c e 25 

कहानी यहाँ का नैतिक है कि अगर यह है: जब हम ddply उपयोग करते हैं, जिसके परिणामस्वरूप प्रकार के रूप में हम चाहते हैं हो जाएगा

d$x1 <- factor(d$x1, levels = c('b','a','c'),ordered = TRUE) 
d$x2 <- factor(d$x2, levels = c('d','f','e'), ordered = TRUE) 

अब ddply किसी ऑर्डर में कुछ आउटपुट कर रहा है जिसका आप इरादा नहीं रखते थे, यह एक अच्छा संकेत है कि आप जिस चर को विभाजित कर रहे हैं उसके लिए आपको ऑर्डर किए गए कारकों का उपयोग करना चाहिए।

+0

धन्यवाद। ऐसा लगता है कि मेरे लिए "लगभग" काम कर रहा है। मैं अपने समारोह के लौटे डेटा में '.sortColumn' कैसे रखूं? 'calculate_T60_Over_T0_Ratio <- समारोह (DF) {' ' ## यकीन है कि सही समय अंक ratio' के लिए इस्तेमाल किया जा रहा बनाने के लिए जाँच करता है ' t60Value = df [जो (df [, "टाइम"] == " टी = 60 ")," परिणाम "]' 't0Value = df [जो (डीएफ [," समय "] ==" टी = 0 ")," परिणाम "]' 'अगर (t0Value == 0) { ' ' प्रिंट ("त्रुटि - शून्य से विभाजित!") ' ' वापसी ("NA") ' '} else { ' ' वापसी (t60Value/t0Value) ' '} ' '}' – James

+0

@ जेम्स यदि आप परिणामों में '.sortColumn' रखना चाहते हैं, तो आप संभवतः 'keep.order' से लाइन 'आउट [, col] <- NULL' को छोड़ सकते हैं। – joran

+0

क्षमा करें, मैं स्पष्ट नहीं था। मुझे 'keeping.order' से त्रुटि मिल रही है क्योंकि '.sortColumn' को मेरे फ़ंक्शन द्वारा वापस नहीं किया जा रहा है (ऊपर देखें)। – James

1

अंत में मैंने मूल डेटा फ्रेम में 'अनुक्रमण' कॉलम जोड़ना समाप्त कर दिया। इसमें sep="_" के साथ दो कॉलम pasted शामिल थे। फिर मैंने 'अनुक्रमण' कॉलम के केवल unique सदस्यों और काउंटर 1:length(df) के एक और डेटा फ्रेम बनाया। मैंने डेटा पर ddply() किया जो एक क्रमबद्ध डेटा फ्रेम लौटा। फिर चीजों को मूल क्रम में वापस लाने के लिए मैंने merge() परिणाम डेटा फ्रेम और इंडेक्स डेटा फ्रेम किया (यह सुनिश्चित करना कि स्तंभों को एक ही चीज़ नाम दिया गया है, यह आसान बनाता है)। अंत में, मैंने order किया और अपरिवर्तनीय कॉलम हटा दिए।

कोई सुरुचिपूर्ण समाधान नहीं है, लेकिन जो काम करता है।

सहायता के लिए धन्यवाद। यह मुझे सही दिशा में सोच रहा है।

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