41

data.frame列「a」と「b」のあるaがあります。列aとbの中で最高と最低を含む「high」と「low」という列を追加したいと思います。

データフレームの行をループせずにこれを行う方法はありますか?

編集:これはOHLCデータ用であるため、高列と低列には、列全体ではなく、同じ行のaとbの間の最高と最低の要素が含まれている必要があります。これがひどい言い回しならごめんなさい。

4

4 に答える 4

48

あなたが探しているように聞こえますpmaxpmin「並列」最大/分):

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).
于 2011-04-08T07:07:39.407 に答える
4

これが私が使用して実装したバージョン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そのため、バージョンが高速であることがわかります。

関数にエラーチェックを追加することで、より良い結果を得ることができます。たとえば、両方のベクトルが同じ長さであるか、比較可能であることを確認します(文字と数値、またはブール値と数値ではありません)。

于 2016-10-26T18:38:44.723 に答える
0

data.frame名がdatの場合。

dat$pmin <- do.call(pmin,dat[c("a","b")])
dat$pmax <- do.call(pmax,dat[c("a","b")])
于 2011-04-08T12:52:56.697 に答える
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)
于 2011-04-08T14:38:13.933 に答える