如何使用R自动化两个矩阵的每列之间的操作?

时间:2016-04-12 10:07:49

标签: r for-loop matrix lapply sapply

我有为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循环吗?

1 个答案:

答案 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

个人评论:

f1sapply()方法)看起来更紧凑,并且#34;清洁&#34;。