मेरे पास एक data.table है जिसे मुझे सूचियों में विभाजित करने की आवश्यकता है। यहाँ एक नमूना डेटा सेट है:

testSet <- data.table(A = 1:2, B = 4:5, C = rep(7:8, times = 50), 
                        D = 9:10, E = 15:16, F = 24:25, G = 27:28,
                        H = 29:30, I = 32:33, J = 35:36, K = 1:50)

जैसा कि आप देख सकते हैं, इसमें 11 कॉलम हैं, जिनमें से प्रत्येक संख्यात्मक है। मुझे 10 कॉलम में मानों से विभाजित करने की आवश्यकता है ताकि सूचियों की एक सूची बनाई जा सके। मैंने निम्नलिखित कार्यात्मक कोड (संदर्भ के लिए मैकबुक एयर) बनाया है:

system.time(testSetLists <- split(testSet, 
                list(testSet[["A"]], testSet[["B"]], testSet[["C"]],
                        testSet[["D"]], testSet[["E"]], testSet[["F"]], 
                        testSet[["G"]], testSet[["H"]], testSet[["I"]], 
                        testSet[["J"]])))

>    user  system elapsed 
    0.759   0.109   0.731 

यह पूरी तरह से काम करता है और मुझे बिल्कुल वही आउटपुट देता है जिसकी मुझे आवश्यकता है। हालांकि, जब मैं केवल एक कॉलम में संख्या सीमा बढ़ाता हूं, जैसे A निम्न डेटा सेट में:

testSet <- data.table(A = 1:5, B = 4:5, C = rep(7:8, times = 50), 
                        D = 9:10, E = 15:16, F = 24:25, G = 27:28,
                        H = 29:30, I = 32:33, J = 35:36, K = 1:50)

system.time(testSetLists <- split(testSet, 
                list(testSet[["A"]], testSet[["B"]], testSet[["C"]],
                        testSet[["D"]], testSet[["E"]], testSet[["F"]], 
                        testSet[["G"]], testSet[["H"]], testSet[["I"]], 
                        testSet[["J"]])))

>    user  system elapsed 
    2.139   0.301   2.054 

आप देख सकते हैं कि A में केवल 3 मान जोड़कर निष्पादित करने का समय प्रसंस्करण समय को तीन गुना कर देता है। अब क्या होता है जब मैं B, D, और J में और मान जोड़ता हूं, जैसे?

testSet <- data.table(A = 1:5, B = 4:9, C = rep(7:8, times = 50), 
                        D = 9:14, E = 15:16, F = 24:25, G = 27:28,
                        H = 29:30, I = 32:33, J = 35:56, K = 1:50)

system.time(testSetLists <- split(testSet, 
                list(testSet[["A"]], testSet[["B"]], testSet[["C"]],
                        testSet[["D"]], testSet[["E"]], testSet[["F"]], 
                        testSet[["G"]], testSet[["H"]], testSet[["I"]], 
                        testSet[["J"]])))

>    user  system elapsed 
  179.356  21.311 176.562

जैसा कि आप देख सकते हैं, यह समाधान अस्थिर है जब मेरे पास प्रत्येक कॉलम में 100 या इतने ही अद्वितीय डेटा बिंदु होते हैं।

मैं इस फ़ंक्शन का उपयोग करके सभी खाली सूचियों को हटा सकता हूं:

testSetLists <- testSetLists[sapply(testSetLists, function(x) dim(x)[1]) > 0]

मेरा प्रश्न यह है: मैं अत्यधिक उच्च CPU समय के बिना समान इनपुट कैसे ले सकता हूं और समान आउटपुट कैसे प्राप्त कर सकता हूं? R के भीतर कोई भी विकल्प टेबल पर है।

1
black_sheep07 30 अप्रैल 2016, 07:24

2 जवाब

सबसे बढ़िया उत्तर

ऐसा प्रतीत होता है कि गणना में इतना समय लगा क्योंकि split प्रदान किए गए कारकों में से प्रत्येक संयोजन को निर्धारित करने का प्रयास करता है। हालांकि, drop=TRUE तर्क सेट किया जा सकता है, इसलिए केवल उन संयोजनों को रखा जाता है जिनमें तत्व होते हैं। आपके अंतिम डेटासेट पर, मेरे पीसी पर:

system.time(testSetLists <- split(testSet,testSet[,.SD,.SDcols=names(testSet)[1:10]]))
#   user  system elapsed 
#128.111   0.343 128.930
system.time(testSetLists <- split(testSet,testSet[,.SD,.SDcols=names(testSet)[1:10]],drop=TRUE))
#   user  system elapsed 
#  0.048   0.000   0.048 

यह भी ध्यान दें कि मैंने उस समय मैन्युअल रूप से लिखने के बजाय, विभाजन को इंगित करने वाले कॉलम कैसे लिए।

5
nicola 30 अप्रैल 2016, 08:46

हाल ही में data.table को अपना split तरीका मिला है। यह कॉलम नामों को विभाजित करने के लिए स्वीकार कर सकता है। f तर्क के लिए पूर्ण कॉलम पास करने की कोई आवश्यकता नहीं है, जैसा कि data.frame के मामले में होता है। यह split.data.frame के विपरीत, समूहीकरण के क्रम को भी सुरक्षित रख सकता है।

library(data.table)
suppressWarnings( # OP data raises recycling warning
    testSet <- data.table(A = 1:5, B = 4:9, C = rep(7:8, times = 50), 
                          D = 9:14, E = 15:16, F = 24:25, G = 27:28,
                          H = 29:30, I = 32:33, J = 35:56, K = 1:50)
)
system.time(dropF <- split(testSet, testSet[,.SD,.SDcols=names(testSet)[1:10]]))
#   user  system elapsed 
#371.684   4.032 115.058
system.time(dropT <- split(testSet, testSet[,.SD,.SDcols=names(testSet)[1:10]], drop=TRUE))
#   user  system elapsed 
#  0.304   0.004   0.097 
system.time(byDropT <- split(testSet, by=names(testSet)[1:10], drop=TRUE, sorted=TRUE))
#   user  system elapsed 
#  0.180   0.000   0.061 
all.equal(
    dropT[sort(names(dropT))],
    byDropT
)
#[1] TRUE

1.9.7 संस्करण स्थापित करने के लिए उपयोग करें:

install.packages("data.table", type = "source", repos = "https://Rdatatable.github.io/data.table")
2
jangorecki 30 अप्रैल 2016, 15:36