获取由子集参数向量定义的多个向量子集的长度

时间:2014-05-22 11:54:27

标签: r vector

我有xn元素的向量。

现在我想得到方案s = subset(x, x<=p)的这个向量的多个子集,其中p将保存多个值,通过向量给出。

最后,我想根据包含p值的向量将这些子集的长度存储在向量中。

你可以帮助我做这个没有循环等吗?

3 个答案:

答案 0 :(得分:2)

另一个内存要求较低的解决方案:

set.seed(42)
x <- rnorm(20) 
p <- c(-1, 0, 1)
## sapply(p, function(pi) sum(x <= pi))
[1] 1 5 8

基准:

library(microbenchmark)
set.seed(42)
x <- rnorm(20000)
p <- rnorm(100)
microbenchmark(setNames(colSums(outer(x, p, "<=")), p), sapply(p, function(pi) sum(x <= pi)))
## Unit: milliseconds
##                                     expr      min       lq  median       uq      max neval
##  setNames(colSums(outer(x, p, "<=")), p) 29.33870 87.21804 88.5226 89.94144 94.34427   100
##     sapply(p, function(pi) sum(x <= pi)) 21.52853 22.23344 22.2959 22.46226 26.13650   100

答案 1 :(得分:1)

set.seed(42)
x <- rnorm(20) 
p <- c(-1, 0, 1)

setNames(colSums(outer(x, p, "<=")), p)
#-1  0  1 
# 3 10 14 

说明:

<=中使用outer测试x的每个元素对p的每个元素。计算colwise sums可得出每个TRUE值的p值。最后,我们使用p值作为名称。

答案 2 :(得分:1)

为了好玩,让我们用Rcpp做吧。在这里,我先对输入进行排序,然后利用它:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector countsmaller(NumericVector x, const NumericVector p) {
  x=x.sort();
  NumericVector sorted = clone(p).sort();
  IntegerVector order=match(p, sorted);
  int count = 0;
  double prob=sorted(0);
  int i=0;
   for(int j = 0; j < x.size(); ++j) {
      if (x(j) <= prob) 
      {
        count++;
      } 
      else 
      {
        if (i < sorted.size()-1)
        {
          sorted(i)=count;
          i++;
          prob=sorted(i);  
          if (x(j) <= prob) count++; else j--;
        }
      }
    }
    sorted(sorted.size()-1) = count;
   return sorted[order-1];
}

它更快吗?

set.seed(42)
x <- rnorm(20000)
p <- rnorm(100)

all.equal(countsmaller(x, p), 
          sapply(p, function(pi) sum(x <= pi)))
#TRUE

library(microbenchmark)
microbenchmark(colSums(outer(x, p, "<=")), 
sapply(p, function(pi) sum(x <= pi)),
countsmaller(x, p)
)

# Unit: milliseconds
#                                 expr       min        lq    median        uq        max neval
#           colSums(outer(x, p, "<=")) 22.354525 64.833602 65.343129 66.161082 149.428049   100
# sapply(p, function(pi) sum(x <= pi)) 12.922805 13.344871 14.444304 15.009727  58.607176   100
#                   countsmaller(x, p)  1.650383  1.703044  1.730453  1.754937   2.222273   100