有一种更短/更优雅/更有效的写作方式吗?

时间:2018-03-13 14:55:53

标签: r

这个R代码有效,但是for循环看起来太长而且很难看,而且我已经读过在R中不建议使用for循环。

我想要做的是将不同长度的矢量从矢量HaarData @ W列表复制到矩阵MyMatrix的行中。

由于向量长度短于矩阵中的列数,我想复制值以填充行。

向量的长度为2 z z∈ℤ,矩阵行长度需要为n <2> ≤n

library(wavelets)


Data <- seq(1, 16)

n <- as.integer(log2(length(Data)))
#Data <- seq(1, 2 ^ n, 1)
HaarData <- dwt(Data, filter = "haar")


#Square matrix to write data
MyMatrix <- matrix(, nrow = n, ncol = 2 ^ n)


row <- 0 #row counter
for (vector in HaarData@W) {
    row <- row + 1
    duplication <- (2 ^ n) / length(vector)
    newRow <- c(rep(vector, each = duplication))
    MyMatrix[row,] <- newRow
}

1 个答案:

答案 0 :(得分:0)

我不确定你为什么要首先进行操作,但以下是我的方法:

library(wavelets)
library(microbenchmark)

Data <- seq(1, 32)
n <- as.integer(log2(length(Data)))

HaarData <- dwt(as.numeric(Data), filter = "haar")

# Abstract operation in the loop in a function, no side effects
duplicate_coefs <- function(filter_coefs, n){
  rep(filter_coefs, each = `^`(2, n - as.integer(log2(length(filter_coefs))) ))
}


microbenchmark(
  old = {
    #Square matrix to write data
    MyMatrix <- matrix(, nrow = n, ncol = 2 ^ n)


    row <- 0 #row counter
    for (vector in HaarData@W) {
      row <- row + 1
      duplication <- (2 ^ n) / length(vector)
      newRow <- c(rep(vector, each = duplication))
      MyMatrix[row,] <- newRow
    }
  }
  ,
  new = {
     n_len <- length(HaarData@W)
     new_result <- matrix(unlist( lapply(HaarData@W, duplicate_coefs, n_len) )
            , nrow = n_len
            , byrow = TRUE)

)

identical(MyMatrix, new_result)

在我的机器上,你可以获得大约50倍的加速

Unit: microseconds
 expr      min        lq       mean    median        uq      max neval
  old 2891.967 2940.0550 3203.14740 2982.5360 3110.3985 6472.223   100
  new   48.519   50.8065   59.04673   56.4805   60.8905  302.845   100

希望这有帮助