2011-06-14 7 views
16

मैंने यह प्रश्न आर मेलिंग सूची पर कई बार पूछा है, लेकिन फिर भी एक संतोषजनक उत्तर नहीं मिला।मिनट के लिए पंक्तिमान() के बराबर()

मान लीजिए मैं एक मैट्रिक्स m

m <- matrix(rnorm(10000000), ncol=10) 

मैं प्रत्येक पंक्ति के माध्य प्राप्त कर सकते हैं:

system.time(rowMeans(m)) 
    user system elapsed 
    0.100 0.000 0.097 

लेकिन द्वारा

system.time(apply(m,1,min)) 
    user system elapsed 
16.157 0.400 17.029 

प्रत्येक पंक्ति के न्यूनतम मूल्य प्राप्त करने लगते हैं 100 गुना से अधिक, क्या इसे गति देने का कोई तरीका है?

उत्तर

15

तेजी से आप pmin इस्तेमाल कर सकते हैं, लेकिन आप अपने मैट्रिक्स के प्रत्येक कॉलम को एक अलग वेक्टर में प्राप्त करना होगा। ऐसा करने का एक तरीका यह है कि इसे डेटा.फ्रेम में परिवर्तित करें, pmin को do.call के माध्यम से कॉल करें (क्योंकि डेटा.फ्रेम सूचियां हैं)।

system.time(do.call(pmin, as.data.frame(m))) 
# user system elapsed 
# 0.940 0.000 0.949 
system.time(apply(m,1,min)) 
# user system elapsed 
# 16.84 0.00 16.95 
+0

मुझे 'do.call' के उपयोग पसंद हैं।मैंने 'पमिन' के बारे में सोचा, लेकिन इसे शामिल करने के लिए एक हल्का तरीका नहीं सोचा। सभी अच्छे बच्चे अपने लक्ष्यों को प्राप्त करने के लिए 'do.call' का उपयोग करने में सक्षम होने लगते हैं ... मुझे इस पर कुछ पढ़ने की ज़रूरत है। – Chase

+0

'do.call' काम में आता है जब आप गतिशील समारोह तर्क बनाने के लिए सक्षम होना चाहते हैं (आम तौर पर तर्क की संख्या' के माध्यम से पारित कर दिया जब ... 'ज्ञात नहीं है)। –

+1

अच्छा जवाब, धन्यवाद! pmin.int साथ() यह था भी एक छोटा सा तेजी से – johannes

5
library("sos") 
findFn("rowMin") 

, BioConductor से जितनी जल्दी rowMeans रूप Biobase पैकेज में एक हिट हो जाता है ...

source("http://bioconductor.org/biocLite.R") 
biocLite("Biobase") 

m <- matrix(rnorm(10000000), ncol=10) 
system.time(rowMeans(m)) 
## user system elapsed 
## 0.132 0.148 0.279 
system.time(apply(m,1,min)) 
## user system elapsed 
## 11.825 1.688 13.603 
library(Biobase) 
system.time(rowMin(m)) 
## user system elapsed 
## 0.688 0.172 0.864 

नहीं है, लेकिन एक बहुत से apply(...,1,min)

+0

धन्यवाद, मुझे एसओएस पैकेज और पंक्ति के बारे में पता नहीं था, मेरी समस्या भी हल करती है। – johannes

+0

'do.call' समाधान के साथ-साथ समय की देखभाल भी करें? –

5

मैं आर 2.13.0 में नए compiler पैकेज बाहर आज़माना चाहते गए हैं। यह अनिवार्य रूप से Dirk here द्वारा उल्लिखित पद का पालन करता है।

library(compiler) 
library(rbenchmark) 
rowMin <- function(x, ind) apply(x, ind, min) 
crowMin <- cmpfun(rowMin) 

benchmark(
     rowMin(m,1) 
    , crowMin(m,1) 
    , columns=c("test", "replications","elapsed","relative") 
    , order="relative" 
    , replications=10) 
) 

और परिणाम:

  test replications elapsed relative 
2 crowMin(m, 1)   10 120.091 1.0000 
1 rowMin(m, 1)   10 122.745 1.0221 

, कम से कम कहने के लिए ही आप की तरह दिखता है कुछ अन्य अच्छा विकल्प मिल गया है Anticlimatic।

+0

धन्यवाद, मैं अपने जवाब में गहरी देखने के लिए होगा, उस के लिए नए इलाके है मुझे :) – johannes

+1

संकलक स्पष्ट लूप के अनुकूलन में बेहतर है। उदाहरण का प्रयास करें: 'rowMin <- function (x) {n <- nrow (x); r <- numeric (n); (i में 1: n) r [i] <- min (x [i,]) ; r} ' – Marek

+3

+1' pmin द्वारा 'प्रकाशन पूर्वाग्रह' –

2

नहीं विशेष रूप से आर-विशेष स्वभाव का है, लेकिन निश्चित रूप से सबसे तेजी से विधि सिर्फ pmin और स्तंभों पर पाश उपयोग करने के लिए है:

x <- m[,1] 
for (i in 2:ncol(m)) x <- pmin(x, m[,i]) 

मेरी मशीन है कि 1e + 07x10 मैट्रिक्स के लिए rowMeans से सिर्फ 3 बार समय लेता है पर, और data.frame के माध्यम से do.call विधि से थोड़ा तेज है।

+0

और एक और गति लाभ से बचने के लिए (एम [, 1], मी [, 2], मी [3], मी [4], मी [, 5 ], एम [, 6], एम [, 7], एम [, 8], एम [, 9], एम [, 10]) '। यहोशू 'as.data.frame' समय लेने वाला है। – Marek

+1

हालांकि टाइपिंग के लिए तेज़ नहीं है, या सामान्य इनपुट के लिए सामान्य :) – mdsumner

+0

मैं यहोशू के उत्तर पर टिप्पणी में अधिक सामान्य समाधान जोड़ता हूं। – Marek

8

आप क्रैन संकुल पर कायम करना चाहते हैं, तो दोनों matrixStats और fBasics संकुल समारोह rowMins [टिप्पणी s जो Biobase समारोह में नहीं है] और अन्य पंक्ति और स्तंभ अनेक प्रकार के आंकड़े की है।

10

पार्टी के लिए बहुत देर हो चुकी है, लेकिन matrixStats के लेखक के रूप में और यदि कोई इसे स्पॉट करता है, तो कृपया ध्यान दें कि matrixStats::rowMins() इन दिनों बहुत तेज़ है, उदा।

library(microbenchmark) 
library(Biobase)  # rowMin() 
library(matrixStats) # rowMins() 
options(digits=3) 

m <- matrix(rnorm(10000000), ncol=10) 

stats <- microbenchmark(
    rowMeans(m), ## A benchmark by OP 
    rowMins(m), 
    rowMin(m), 
    do.call(pmin, as.data.frame(m)), 
    apply(m, MARGIN=1L, FUN=min), 
    times=10 
) 

> stats 
Unit: milliseconds 
          expr min  lq mean median  uq max 
         rowMeans(m) 77.7 82.7 85.7 84.4 90.3 98.2 
         rowMins(m) 72.9 74.1 88.0 79.0 90.2 147.4 
         rowMin(m) 341.1 347.1 395.9 383.4 395.1 607.7 
    do.call(pmin, as.data.frame(m)) 326.4 357.0 435.4 401.0 437.6 657.9 
apply(m, MARGIN = 1L, FUN = min) 3761.9 3963.8 4120.6 4109.8 4198.7 4567.4 
+0

@ हेनरिक बीबी यह बहुत अच्छा होगा अगर matrixStats rowMins ने डेटा.फ्रेम पर भी काम किया है (इसे पहले मैट्रिक्स में बदलने की आवश्यकता के बिना) – skan

+1

@skan, दुर्भाग्य से यह स्पष्ट नहीं है कि यह विभिन्न कारणों से matrixStats से संबंधित है, कृपया https://github.com/HenrikBengtsson/matrixStats/issues/18 – HenrikB

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