Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中使用apply加上一个向量参数_R_Vector_Matrix_Apply - Fatal编程技术网

在R中使用apply加上一个向量参数

在R中使用apply加上一个向量参数,r,vector,matrix,apply,R,Vector,Matrix,Apply,我有一个大小为10000 x 100的矩阵和一个长度为100的向量。我想对矩阵的每一列应用一个自定义函数percentile,它接受一个向量参数和一个标量参数,这样在迭代j时,percentile使用的参数是矩阵的第j列和向量的条目j。是否有一种方法可以使用其中一个apply函数来执行此操作 这是我的密码。它运行,但不返回正确的结果 percentile <- function(x, v){ length(x[x <= v]) / length(x) } X <- mat

我有一个大小为10000 x 100的矩阵和一个长度为100的向量。我想对矩阵的每一列应用一个自定义函数percentile,它接受一个向量参数和一个标量参数,这样在迭代j时,percentile使用的参数是矩阵的第j列和向量的条目j。是否有一种方法可以使用其中一个apply函数来执行此操作

这是我的密码。它运行,但不返回正确的结果

percentile <- function(x, v){
  length(x[x <= v]) / length(x)
}

X <- matrix(runif(10000 * 100), nrow = 10000, ncol = 100)
y <- runif(100)
result <- apply(X, 2, percentile, v = y)
我一直使用的解决方法是将y附加到X,然后重新编写百分位函数,如下所示

X <- rbind(X, y)
percentile2 <- function(x){
  v <- x[length(x)]
  x <- x[-length(x)]
  length(x[x <= v]) / length(x)
}
result <- apply(X, 2, percentile2)

这段代码确实返回了正确的结果,但我更喜欢优雅一点的代码。

我认为最简单、最清晰的方法是使用for循环:

速度方面请参见下面的一些基准测试for循环并没有那么糟糕,至少在这种情况下它比使用apply更快。行和和和向量循环的技巧更快,比使用apply的解决方案快10倍以上


我认为最简单、最清晰的方法是使用for循环:

速度方面请参见下面的一些基准测试for循环并没有那么糟糕,至少在这种情况下它比使用apply更快。行和和和向量循环的技巧更快,比使用apply的解决方案快10倍以上

如果你知道R是矢量化的,并且知道正确的函数,你可以完全避免循环,并且在一条相对简单的直线上完成整个过程

 colSums(  t( t( X ) <= y ) ) / nrow( X ) 
显然,因为它不使用任何R循环,所以在这个小矩阵上要快10倍

由于@flodel:

如果你知道R是矢量化的,并且知道正确的函数,你可以完全避免循环,并且在一条相对简单的直线上完成整个过程

 colSums(  t( t( X ) <= y ) ) / nrow( X ) 
显然,因为它不使用任何R循环,所以在这个小矩阵上要快10倍

由于@flodel:


+我没看到你在所有其他东西中有答案。我认为你应该更强调这一点,因为这是一个很好的答案。我留下我的答案,因为我已经解释了它是如何工作的。@SimonO101我编辑了我的答案。我希望它现在更加突出。我也参考了你的答案来解释。+1我没有看到你的答案和其他的东西一样。我认为你应该更强调这一点,因为这是一个很好的答案。我留下我的答案,因为我已经解释了它是如何工作的。@SimonO101我编辑了我的答案。我希望它现在更加突出。我也参考了你的答案来做解释。效果很好!谢谢工作完美!谢谢嗨,欢迎来到苏。由于您是新来的,您可能希望阅读网站的和部分,以帮助您充分利用它。如果一个答案确实解决了你的问题,你可能想要考虑一下投票和/或标记它被接受来显示问题已经被答案,通过在适当的答案旁边划上绿色的小复选标记。你没有义务这样做,但它有助于保持网站清洁,没有未回答的问题,并奖励那些花时间解决你问题的人。嗨,欢迎使用SO。由于您是新来的,您可能希望阅读网站的和部分,以帮助您充分利用它。如果一个答案确实解决了你的问题,你可能想要考虑一下投票和/或标记它被接受来显示问题已经被答案,通过在适当的答案旁边划上绿色的小复选标记。你没有义务这么做,但这有助于保持网站上没有未回答的问题,并奖励那些花时间解决你问题的人。
result3 <- mapply(percentile, as.data.frame(X), y)
> 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
 colSums(  t( t( X ) <= y ) ) / nrow( X ) 
res1 <- apply(X2, 2, percentile2)
res2 <- colSums(  t( t( X ) <= y ) ) / nrow( X )
identical( res1 , res2 )
[1] TRUE
     rowMeans(  t(X) <= y  )