【问题标题】:can I speed up iteration process in R?我可以加快 R 中的迭代过程吗?
【发布时间】:2016-11-21 04:33:08
【问题描述】:

我对 R 中的迭代缺乏经验,并希望在我在网站中实施一些分析时加快流程。

我发现了一个非常有用的教程,它允许我遍历一个矩阵,挑选出高于某个阈值 (>0.01) 的标准数据,然后用这些值渗透三个向量:“源、目标和 corr”,最终使一个组织良好的数据框。

source=c()
target=c()
corr<-c()

g1<-rownames(adj_mat)[1:dim(adj_mat)[1]]
g2<-g1

for(gene in g1){
  for(gen in g2){
    if(adj_mat[gene,gen]>0.01){
      source<-c(source,gene)
      target<-c(target,gen)
      corr<-c(corr,adj_mat[gene,gen])
    }
  }
}
network<-data.frame(source,target,corr)

虽然这对于维度为 1000、500 的小矩阵非常有用,但对于维度为 10000、700...的小矩阵,它需要大量的时间。

矩阵来自一个文件,每次都会上传到网站并在网站中读取,所以我无法适应“来源等”。对象大小与矩阵大小一致,因为每个新上传的文件的大小都不同。

谁能告诉我在 R 中是否有更有效的方法来做到这一点?

【问题讨论】:

  • 变量m是什么?我建议使用索引进行迭代(for(i in 1:nrow(adj_mat))),并且正如@Paul Hiemstra 指出的那样,预分配。例如:source
  • 抱歉我已经纠正了这个错误

标签: r matrix iteration


【解决方案1】:

我现在能看到的最大问题是你迭代地构建了一些数据结构,即sourcetargetcorr。通过将对象预分配到正确的大小并使用索引来放置值,您可以极大地加快代码速度。

您可以通过矢量化操作来进一步改进您的代码。例如,确定m 的哪些部分大于0.01 可以这样轻松完成:

m[m > 0.01]

并获取您的数据结构sourcetargetcorr

matching_indices = which(m > 0.01, arr.ind = TRUE)
source = matching_indices[,1]
target  = matching_indices[,2]
corr = m[m > 0.01]

这只是示例代码,我不完全确定这是否是您需要的。但它为实现这一目标迈出了良好的一步。

【讨论】:

  • 这听起来真的很有用,你能举个例子或链接到示例代码吗?谢谢
  • 我扩展了我的答案。如果没有适当的可重现示例,很难走得更远。
  • 啊,抱歉,您的意思是将索引拟合到文件的给定大小?是的,矩阵将来自上传到网站的文件-每次都不同大小,所以我不能这样做
  • 为什么不呢?您可以在每次获取文件时提取文件的大小,并相应地进行预分配。但是,我会简单地将您的解决方案矢量化,这样就不需要预先分配。
  • 也许我写的这个教程可以对矢量化等有所了解:stcorp.nl/R_course/tutorial_control_flow.html.
【解决方案2】:

向量化对于编写高性能 R 非常重要。这允许在本机代码中完成尽可能多的工作,而 R 和本机代码之间的值传输最少。

例如:

# Slow
a <- c(1, 2, 3)
b <- c(4, 5, 6)

r <- c()

for (i in 1:length(a)) {
    r <- c(r, a[i] + b[i]);
}

# Fast
r <- a + b

后者更快,因为slow 方法调用+ 3 次,每次迭代一次,而fast 方法调用+ 一次。你应该尽可能多地批量处理。它的代码也更短!

但是条件句呢?假设你要优化:

# Slow
a <- c(1, 2, 3)
b <- c(4, 5, 6)

r <- c()

for (i in 1:length(a)) {
    if (a[i] > b[i] / 2) {
        r <- c(r, a[i] + b[i]);
    } else {
        r <- c(r, a[i] - b[i]);
    }
}

你可以使用ifelse

# Fast
a <- c(1, 2, 3)
b <- c(4, 5, 6)

r <- ifelse(a > b / 2, a + b, a - b)

查看@PaulHiemstra 对代码应用程序的回答。

【讨论】:

    猜你喜欢
    • 2011-12-19
    • 2012-10-30
    • 2011-12-22
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多