我认为最简单和最清晰的方法是使用for
循环:
result2 <- numeric(ncol(X))
for (i in seq_len(ncol(X))) {
result2[i] <- sum(X[,i] <= y[i])
}
result2 <- result2 / nrow(X)
我能想到的最快和最短的解决方案是:
result1 <- rowSums(t(X) <= y) / nrow(X)
SimonO101 在他的回答中解释了这是如何工作的。正如我所说,它很快。但是,缺点是不太清楚这里到底计算了什么,尽管您可以通过将这段代码放在一个命名良好的函数中来解决这个问题。
florel 还建议了mapply
一个apply
可以在多个向量上工作的解决方案。但是,要使其工作,您首先需要将每个列或矩阵放在 a list
or中data.frame
:
result3 <- mapply(percentile, as.data.frame(X), y)
在速度方面(请参阅下面的一些基准测试)for-loop 并没有那么糟糕,而且它比使用apply
(至少在这种情况下)更快。向量回收的技巧rowSums
更快,比使用apply
.
> X <- matrix(rnorm(10000 * 100), nrow = 10000, ncol = 100)
> y <- runif(100)
>
> system.time({result1 <- rowSums(t(X) <= y) / nrow(X)})
user system elapsed
0.020 0.000 0.018
>
> system.time({
+ X2 <- rbind(X, y)
+ percentile2 <- function(x){
+ v <- x[length(x)]
+ x <- x[-length(x)]
+ length(x[x <= v]) / length(x)
+ }
+ result <- apply(X2, 2, percentile2)
+ })
user system elapsed
0.252 0.000 0.249
>
>
> system.time({
+ result2 <- numeric(ncol(X))
+ for (i in seq_len(ncol(X))) {
+ result2[i] <- sum(X[,i] <= y[i])
+ }
+ result2 <- result2 / nrow(X)
+ })
user system elapsed
0.024 0.000 0.024
>
> system.time({
+ result3 <- mapply(percentile, as.data.frame(X), y)
+ })
user system elapsed
0.076 0.000 0.073
>
> all(result2 == result1)
[1] TRUE
> all(result2 == result)
[1] TRUE
> all(result3 == result)
[1] TRUE