如何使用R自动化两个矩阵的每列之间的操作?
我有为MAPE编写的通用函数(平均绝对百分比误差) 并预测为如何使用R自动化两个矩阵的每列之间的操作?,r,for-loop,matrix,lapply,sapply,R,For Loop,Matrix,Lapply,Sapply,我有为MAPE编写的通用函数(平均绝对百分比误差) 并预测为 yp = matrix(c(12, 13, 14, 12, 15, 17, 24, 22, 28),byrow=TRUE,ncol=3) 这可以手动为每个列执行,如mape(y[,1],yp[,1]) 我如何使用R自动化在大维度矩阵的每列之间执行操作的过程(也包括任何其他操作-不仅仅是MAPE)?使用apply/sapply可以避免FOR循环吗?更新: 当然,mape可以矢量化: mapeVec <- function(y,
yp = matrix(c(12, 13, 14, 12, 15, 17, 24, 22, 28),byrow=TRUE,ncol=3)
这可以手动为每个列执行,如mape(y[,1],yp[,1])
我如何使用R自动化在大维度矩阵的每列之间执行操作的过程(也包括任何其他操作-不仅仅是MAPE)?使用apply/sapply可以避免FOR循环吗?更新:
当然,mape可以矢量化:
mapeVec <- function(y, yhat)
colMeans(abs((y-yhat)/y))
f3 <- function() { mapeVec(y, yp) }
Unit: milliseconds
expr min lq mean median uq max neval cld
f1() 33.677431 34.121107 35.494355 34.441823 35.078125 46.16782 100 b
f2() 33.558224 33.970123 35.609414 34.239525 34.881354 49.99195 100 b
f3() 8.344952 8.525146 9.218695 8.568763 8.709681 17.82791 100 a
identical(f1(), f3()) # TRUE
微基准:
个人评论:
f1
(sapply()
approach)看起来更加紧凑和“干净” 更新:
当然,mape可以矢量化:
mapeVec <- function(y, yhat)
colMeans(abs((y-yhat)/y))
f3 <- function() { mapeVec(y, yp) }
Unit: milliseconds
expr min lq mean median uq max neval cld
f1() 33.677431 34.121107 35.494355 34.441823 35.078125 46.16782 100 b
f2() 33.558224 33.970123 35.609414 34.239525 34.881354 49.99195 100 b
f3() 8.344952 8.525146 9.218695 8.568763 8.709681 17.82791 100 a
identical(f1(), f3()) # TRUE
微基准:
个人评论:
f1
(sapply()
approach)看起来更加紧凑和“干净” 如果另一种选择是使用apply
或sapply
,您可以安全地将用于
循环,基本上没有任何负面影响。用apply
替换循环不会加快速度。如果替代方法是使用apply
或sapply
,则可以安全地使用for
循环,基本上没有任何负面影响。用apply
替换循环不会加快速度。可以用seq(nrow(y))
替换seq(1:dim(y)[1])
。它没有改变任何东西,只是使长度从何而来变得更加明显。无法抗拒:microbenchmark(seq(1:dim(y)[1]),seq(nrow(y)),times=1000)
给出了10.82
vs9.88
的意思和9.87
vs8.69
中间值。这是因为你使用了seq(1:dim(y)[1])
,也就是说,你基本上是两次排序。如果改用seq(dim(y)[1])
则得到完全相同的结果。如果您试图优化速度,请改用seq_len
。您可以将seq(1:dim(y)[1])
替换为seq(nrow(y))
。它没有改变任何东西,只是使长度从何而来变得更加明显。无法抗拒:microbenchmark(seq(1:dim(y)[1]),seq(nrow(y)),times=1000)
给出了10.82
vs9.88
的意思和9.87
vs8.69
中间值。这是因为你使用了seq(1:dim(y)[1])
,也就是说,你基本上是两次排序。如果改用seq(dim(y)[1])
则得到完全相同的结果。如果您试图优化速度,请改用seq_len
。
mapeVec <- function(y, yhat)
colMeans(abs((y-yhat)/y))
f3 <- function() { mapeVec(y, yp) }
Unit: milliseconds
expr min lq mean median uq max neval cld
f1() 33.677431 34.121107 35.494355 34.441823 35.078125 46.16782 100 b
f2() 33.558224 33.970123 35.609414 34.239525 34.881354 49.99195 100 b
f3() 8.344952 8.525146 9.218695 8.568763 8.709681 17.82791 100 a
identical(f1(), f3()) # TRUE
mape <- function(y, yhat)
mean(abs((y - yhat)/y))
y <- matrix(c(11, 12, 12, 12, 14, 16, 23, 21, 28), nrow = 3, ncol = 3)
yp = matrix(c(12, 13, 14, 12, 15, 17, 24, 22, 28), nrow = 3, ncol = 3)
sapply(seq(nrow(y)), function(id) { mape(y[,id], yp[,id]) })
library(microbenchmark)
mape <- function(y, yhat)
mean(abs((y - yhat)/y))
y <- matrix(rnorm(1000000), nrow = 1000, ncol = 1000)
yp = matrix(rnorm(1000000), nrow = 1000, ncol = 1000)
f1 <- function() { sapply(seq(nrow(y)), function(id) { mape(y[,id], yp[,id]) }) }
f2 <- function() {
a <- vector(mode = "numeric", length = nrow(y))
for(id in seq(nrow(y))) {
a[id] <- mape(y[,id], yp[,id])
}
a
}
microbenchmark(
f1(),
f2()
)
Unit: milliseconds
expr min lq mean median uq max neval cld
f1() 33.28310 34.15209 36.57389 35.42845 36.20803 48.11936 100 a
f2() 34.14755 34.78859 37.65782 36.33395 37.06874 64.10664 100 a