我有为MAPE编写的通用函数(平均绝对百分比误差)
mape <- function(y, yhat)
mean(abs((y - yhat)/y))
我想计算两个不同矩阵的每列之间的MAPE。 假设它们采用以下格式
y = matrix(c(11, 12, 12, 12, 14, 16, 23, 21, 28),byrow=TRUE,ncol=3)
并预测为
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循环吗?
答案 0 :(得分:2)
当然,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
sapply
的 seq(nrow(y))
应该可以解决问题:
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
f1
(sapply()
方法)看起来更紧凑,并且#34;清洁&#34;。