2015-01-28 9 views
8

मुझे do.call पसंद है। मुझे एक सूची में फ़ंक्शन तर्कों को संग्रहीत करने में सक्षम होना पसंद है और फिर उन्हें किसी दिए गए फ़ंक्शन में विभाजित करना पसंद है।बड़े डेटासेट के लिए do.call करने के लिए वैकल्पिक

उदाहरण के लिए, मैं अक्सर अपने आप को इस पद्धति का उपयोग कर विभिन्न पूर्वानुमान आधारित मॉडल की एक सूची फिट करने के लिए, के साथ कुछ साझा किया और एक मॉडल के लिए कुछ अद्वितीय पैरामीटर लगता है:

library(caret) 
global_args <- list(
    x=iris[,1:3], 
    y=iris[,4], 
    trControl=trainControl(
    method='cv', 
    number=2, 
    returnResamp='final', 
    ) 
) 
global_args$trControl$index <- createFolds(
    global_args$y, 
    global_args$trControl$number 
) 
model_specific_args <- list(
    'lm' = list(method='lm', tuneLength=1), 
    'nn' = list(method='nnet', tuneLength=3, trace=FALSE), 
    'gbm' = list(
    method='gbm', 
    verbose=FALSE, 
    tuneGrid=expand.grid(
     n.trees=1:100, 
     interaction.depth=c(2, 3), 
     shrinkage=c(.1, .01) 
    ) 
) 
) 
list_of_models <- lapply(model_specific_args, function(args){ 
    return(do.call(train, c(global_args, args), quote=TRUE)) 
}) 
resamps <- resamples(list_of_models) 
dotplot(resamps, metric='RMSE') 

global_args तर्क है कि सभी के लिए समान हैं शामिल मॉडल के, और model_specific_args में मॉडल-विशिष्ट तर्कों की सूचियां शामिल हैं। मैं model_specific_args पर लूप, global_args के साथ प्रत्येक तत्व को संयोजित करता हूं, और फिर मॉडल फिटिंग फ़ंक्शन पर अंतिम तर्क सूची को पास करने के लिए do.call का उपयोग करता हूं।

हालांकि यह कोड दृश्यमान रूप से सुरुचिपूर्ण है, इसका प्रदर्शन भयानक है: do.call सचमुच पूरे एक्स डेटासेट को पाठ के रूप में क्रमबद्ध करता है और फिर इसे मॉडल फिटिंग फ़ंक्शन में भेज देता है। यदि एक्स कुछ जीबी डेटा है तो यह रैम की पागल राशि का उपयोग करता है और आमतौर पर विफल रहता है।

print(list_of_models[[1]]$call) 

वहाँ do.call या call का उपयोग किए बिना किसी तरह से आर में एक समारोह के लिए तर्कों की सूची पारित करने के लिए है?

+0

क्या आपने plyr पैकेज से rbind.fill की कोशिश की है। मैंने यह जानने के लिए कोड नहीं पढ़ा है कि अंतिम उत्पाद डेटा फ्रेम है, लेकिन यदि ऐसा है, तो rbind.fill बराबर do.call (rbind, ...) से काफी तेज़ है। अन्य मामलों में, मुझे भी कमी (।) – jimmyb

+0

@jimmyb का उपयोग करके सफलता मिली है, मुझे नहीं लगता कि 'rbind.fill' या' Reduce' यहां उचित हैं। मैं 'data.frames 'को गठबंधन करने की कोशिश नहीं कर रहा हूं, मैं फ़ंक्शन में तर्कों की सूचियां पास करने का प्रयास कर रहा हूं। – Zach

+0

क्या [यह] (http://stackoverflow.com/questions/13923301/is-there-a-work-around-for-slow-performance-of-do-callcbind-xts-in-r-2-15) मदद? – r2evans

उत्तर

1

@ r2evans टिप्पणी के आधार पर, यहां एक संभावित समाधान है: quote() तर्कों की सूची में बड़ी वस्तुएं। वे तो वैश्विक वातावरण से खींचा जाएगा जब do.call समारोह का मूल्यांकन करता है:

library(caret) 
x <- iris[,1:3] 
y <- iris[,4] 
global_args <- list(
    x=quote(x), 
    y=quote(y), 
    trControl=trainControl(
    method='cv', 
    number=2, 
    returnResamp='final' 
) 
) 
global_args$trControl$index <- createFolds(
    y, 
    global_args$trControl$number 
) 
model_specific_args <- list(
    'lm' = list(method='lm', tuneLength=1), 
    'nn' = list(method='nnet', tuneLength=3, trace=FALSE), 
    'gbm' = list(
    method='gbm', 
    verbose=FALSE, 
    tuneGrid=expand.grid(
     n.trees=1:100, 
     interaction.depth=c(2, 3), 
     shrinkage=c(.1, .01) 
    ) 
) 
) 
list_of_models <- lapply(model_specific_args, function(args){ 
    return(do.call(train, c(global_args, args), quote=FALSE)) 
}) 
print(list_of_models[[1]]$call) 

परिणाम में काफी छोटा है:

train.default(x = x, y = y, method = "lm", trControl = list(method = "cv", 
    number = 2, repeats = 1, p = 0.75, initialWindow = NULL, 
    horizon = 1, fixedWindow = TRUE, verboseIter = FALSE, returnData = TRUE, 
    returnResamp = "final", savePredictions = FALSE, classProbs = FALSE, 
    summaryFunction = function (data, lev = NULL, model = NULL) 
    { 
     if (is.character(data$obs)) 
      data$obs <- factor(data$obs, levels = lev) 
     postResample(data[, "pred"], data[, "obs"]) 
    }, selectionFunction = "best", preProcOptions = list(thresh = 0.95, 
     ICAcomp = 3, k = 5), index = list(Fold1 = c(6L, 7L, 11L, 
    12L, 13L, 14L, 15L, 16L, 21L, 22L, 25L, 26L, 29L, 32L, 34L, 
    35L, 36L, 37L, 38L, 39L, 40L, 41L, 48L, 49L, 50L, 51L, 52L, 
    54L, 57L, 58L, 59L, 64L, 65L, 66L, 67L, 69L, 70L, 71L, 72L, 
    74L, 78L, 80L, 83L, 84L, 85L, 91L, 92L, 93L, 95L, 98L, 99L, 
    100L, 103L, 105L, 106L, 107L, 109L, 111L, 112L, 116L, 118L, 
    122L, 123L, 124L, 125L, 128L, 130L, 132L, 133L, 135L, 138L, 
    141L, 143L, 144L, 145L, 148L), Fold2 = c(1L, 2L, 3L, 4L, 
    5L, 8L, 9L, 10L, 17L, 18L, 19L, 20L, 23L, 24L, 27L, 28L, 
    30L, 31L, 33L, 42L, 43L, 44L, 45L, 46L, 47L, 53L, 55L, 56L, 
    60L, 61L, 62L, 63L, 68L, 73L, 75L, 76L, 77L, 79L, 81L, 82L, 
    86L, 87L, 88L, 89L, 90L, 94L, 96L, 97L, 101L, 102L, 104L, 
    108L, 110L, 113L, 114L, 115L, 117L, 119L, 120L, 121L, 126L, 
    127L, 129L, 131L, 134L, 136L, 137L, 139L, 140L, 142L, 146L, 
    147L, 149L, 150L)), indexOut = NULL, timingSamps = 0, predictionBounds = c(FALSE, 
    FALSE), seeds = NA, adaptive = list(min = 5, alpha = 0.05, 
     method = "gls", complete = TRUE), allowParallel = TRUE), 
    tuneLength = 1) 

यह अभी भी अच्छा होगा अन्य सभी विकल्पों को क्रमानुसार करने की जरूरत नहीं करने के लिए हालांकि। विशेष रूप से तीसरा मॉडल का कॉल अभी भी बड़ा है: print(list_of_models[[3]]$call)

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