2011-04-08 13 views
19

मेरे पास data.frame कॉलम "ए" और "बी" के साथ है। मैं "उच्च" और "कम" नामक कॉलम जोड़ना चाहता हूं जिसमें कॉलम ए और बी के बीच उच्चतम और निम्नतम शामिल है।क्या एक वेक्टरीकृत समानांतर अधिकतम() और न्यूनतम() है?

क्या डेटाफ्रेम में लाइनों पर लूप किए बिना ऐसा करने का कोई तरीका है?

संपादित करें: यह ओएचएलसी डेटा के लिए है, और इसलिए उच्च और निम्न कॉलम में एक ही पंक्ति पर ए और बी के बीच उच्चतम और निम्नतम तत्व होना चाहिए, और पूरे कॉलम में नहीं। क्षमा करें अगर यह बुरी तरह से शब्द है।

Extremes     package:base     R Documentation 

Maxima and Minima 

Description: 

    Returns the (parallel) maxima and minima of the input values. 

Usage: 

    max(..., na.rm = FALSE) 
    min(..., na.rm = FALSE) 

    pmax(..., na.rm = FALSE) 
    pmin(..., na.rm = FALSE) 

    pmax.int(..., na.rm = FALSE) 
    pmin.int(..., na.rm = FALSE) 

Arguments: 

    ...: numeric or character arguments (see Note). 

    na.rm: a logical indicating whether missing values should be 
      removed. 

Details: 

    ‘pmax’ and ‘pmin’ take one or more vectors (or matrices) as 
    arguments and return a single vector giving the ‘parallel’ maxima 
    (or minima) of the vectors. The first element of the result is 
    the maximum (minimum) of the first elements of all the arguments, 
    the second element of the result is the maximum (minimum) of the 
    second elements of all the arguments and so on. Shorter inputs 
    are recycled if necessary. ‘attributes’ (such as ‘names’ or 
    ‘dim’) are transferred from the first argument (if applicable). 

उत्तर

23

लग रहा है।

dat$pmin <- do.call(pmin,dat[c("a","b")]) 
dat$pmax <- do.call(pmax,dat[c("a","b")]) 
+0

धन्यवाद! एक दूसरे में कोशिश कर रहे होंगे। –

0

यदि आपका data.frame नाम Dat है: आप pmax और pmin ("समांतर" अधिकतम/मिनट) के लिए देख रहे की तरह

0

एक अन्य संभावित समाधान:

set.seed(21) 
Data <- data.frame(a=runif(10),b=runif(10)) 
Data$low <- apply(Data[,c("a","b")], 1, min) 
Data$high <- apply(Data[,c("a","b")], 1, max) 
0

यहाँ एक संस्करण मैं Rcpp का उपयोग कर लागू किया है। मैंने अपने संस्करण के साथ pmin की तुलना की, और मेरा संस्करण लगभग 3 गुना तेज है।

library(Rcpp) 

cppFunction(" 
    NumericVector min_vec(NumericVector vec1, NumericVector vec2) { 
    int n = vec1.size(); 
    if(n != vec2.size()) return 0; 
    else { 
     NumericVector out(n); 
     for(int i = 0; i < n; i++) { 
     out[i] = std::min(vec1[i], vec2[i]); 
     } 
     return out; 
    } 
    } 
") 

x1 <- rnorm(100000) 
y1 <- rnorm(100000) 

microbenchmark::microbenchmark(min_vec(x1, y1)) 
microbenchmark::microbenchmark(pmin(x1, y1)) 

x2 <- rnorm(500000) 
y2 <- rnorm(500000) 

microbenchmark::microbenchmark(min_vec(x2, y2)) 
microbenchmark::microbenchmark(pmin(x2, y2)) 

100.000 तत्वों के लिए microbenchmark समारोह उत्पादन होता है:

> microbenchmark::microbenchmark(min_vec(x1, y1)) 
Unit: microseconds 
      expr  min  lq  mean median  uq 
min_vec(x1, y1) 215.731 222.3705 230.7018 224.484 228.1115 
    max neval 
284.631 100 
> microbenchmark::microbenchmark(pmin(x1, y1)) 
Unit: microseconds 
     expr  min  lq  mean median  uq  max 
pmin(x1, y1) 891.486 904.7365 943.5884 922.899 954.873 1098.259 
neval 
    100 

और 500,000 तत्वों के लिए:

> microbenchmark::microbenchmark(min_vec(x2, y2)) 
Unit: milliseconds 
      expr  min  lq  mean median  uq 
min_vec(x2, y2) 1.493136 2.008122 2.109541 2.140318 2.300022 
    max neval 
2.97674 100 
> microbenchmark::microbenchmark(pmin(x2, y2)) 
Unit: milliseconds 
     expr  min  lq  mean median  uq 
pmin(x2, y2) 4.652925 5.146819 5.286951 5.264451 5.445638 
     max neval 
6.639985 100 

तो आप देख सकते Rcpp संस्करण तेज है।

आप फ़ंक्शन में कुछ त्रुटि जांच जोड़कर इसे बेहतर बना सकते हैं, उदाहरण के लिए: जांचें कि दोनों वैक्टर समान लंबाई हैं, या वे तुलनीय हैं (वर्ण बनाम संख्यात्मक, या बूलियन बनाम संख्यात्मक नहीं)।