【问题标题】:There is a shorter/elegant/efficient way of writing this?有一种更短/优雅/有效的写法吗?
【发布时间】:2018-03-13 14:55:53
【问题描述】:

这个 R 代码可以工作,但是 for 循环看起来太长太丑了,而且我读过 R 中不建议使用 for 循环。

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

由于向量长度小于矩阵中的列数,我想复制这些值来填充行。

向量的长度为 2z z ∈ ℤ ,矩阵行长度需要为 n 这样 2z ≤ 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
}

【问题讨论】:

  • 关于使运行代码看起来更漂亮的问题并不是 Stack Overflow 的主题。也许Code Review 是一个更好的地方。
  • 试试do.call(rbind,list(a=1:3, b=1:2, c=1:5))
  • @Jimbou 你的意思是用MyMatrix &lt;- do.call(rbind, do.call(rep(?, each = n/length(?)),HaarData@W))替换for循环你怎么指定“?
  • 直接使用列表HaarData@W。尝试使用dput() 和您的预期输出来包含您的数据。我现在不能安装额外的包,所以用这种方式帮助你会更容易。

标签: r


【解决方案1】:

我不知道你为什么要首先做这个手术,但是我的方法如下:

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

希望对你有帮助

【讨论】:

  • 这正是我想要的。谢谢(我想对小波系数进行主成分分析)。在这里,有奖给你youtube.com/watch?v=vT2hFTKCXx4
  • 好吧,您可能想看看irlba 包,它实现了一种算法,可以直接在稀疏矩阵上执行 PCA - 小波系数的默认表示。而不是使矩阵密集,然后进行 PCA ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 2011-05-12
  • 1970-01-01
相关资源
最近更新 更多