我有x
个n
元素的向量。
现在我想得到方案s = subset(x, x<=p)
的这个向量的多个子集,其中p
将保存多个值,通过向量给出。
最后,我想根据包含p
值的向量将这些子集的长度存储在向量中。
你可以帮助我做这个没有循环等吗?
答案 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