非常慢:xts将列除以第一行

时间:2016-05-06 23:12:38

标签: r xts

知道为什么这么慢?

我正在尝试将矩阵索引到第一行。

> nrow(cfm2)
[1] 8326
> head(cfm2)
              TSX      TY1  GC1:CAD  CL1:CAD
1983-12-01 2558.0 80.43750 497.3676 36.29842
1983-12-02 2550.2 79.84375 496.1024 36.55753
1983-12-05 2540.2 79.81250 496.9146 36.49022
1983-12-06 2536.8 79.84375 495.9524 36.41626
1983-12-07 2549.3 79.68750 501.9910 36.16226
1983-12-08 2535.5 79.25000 484.1805 36.44115

我试过这个,得到了奇怪的结果:

> cfm <- cfm2 / drop(coredata(cfm2[1]))
> head(cfm)
                  TSX        TY1    GC1:CAD    CL1:CAD
1983-12-01  1.0000000 0.16172644  0.1944361 0.07298106
1983-12-02 31.7041175 2.19964833  6.1675513 1.00713855
1983-12-05  5.1072883 0.03120113  0.9990891 0.01426514
1983-12-06 69.8873485 0.99261849 13.6631959 0.45272736
1983-12-07  0.9965989 0.16021851  0.1962435 0.07270731
1983-12-08 31.5213675 2.18329086  6.0193380 1.00393224

我尝试了这个,得到了正确的结果,但是花了很长时间。

test.cfm <- function(cfm){
  cfm1 <- cfm
  for(cc in 1:ncol(cfm)){
    for(rr in 1:nrow(cfm)){
      coredata(cfm[rr,cc]) <- 100 * coredata(cfm1[rr,cc]) / coredata(cfm1[1,cc])
    }
  }
  return(cfm)
}

> system.time(cfm <- test.cfm(cfm2))
   user  system elapsed 
 17.809   4.886  22.896 
> head(cfm)
                 TSX       TY1   GC1:CAD   CL1:CAD
1983-12-01 100.00000 100.00000 100.00000 100.00000
1983-12-02  99.69507  99.26185  99.74561 100.71385
1983-12-05  99.30414  99.22300  99.90891 100.52841
1983-12-06  99.17123  99.26185  99.71545 100.32465
1983-12-07  99.65989  99.06760 100.92956  99.62491
1983-12-08  99.12041  98.52370  97.34861 100.39322

知道发生了什么事吗?我相信对于那些有经验的人来说这一定是显而易见的,但我很困惑......

1 个答案:

答案 0 :(得分:3)

你的循环遍布每一个。单。元件。让R&#39的矢量化帮助你。

test.cfm.new <- function(cfm) {
  for(cc in 1:ncol(cfm)) {
      cfm[,cc] <- cfm[,cc] / drop(coredata(cfm[1,cc]))
  }
  return(100 * cfm)
}
require(xts)
data(sample_matrix)
x <- as.xts(sample_matrix)
system.time(cfm <- test.cfm(x))
#    user  system elapsed 
#   0.111   0.000   0.112
system.time(cfm.new <- test.cfm.new(x))
#    user  system elapsed 
#   0.000   0.000   0.001 
all.equal(cfm, cfm.new)
# [1] TRUE