【问题标题】:Making a nested for loop run faster in R使嵌套的 for 循环在 R 中运行得更快
【发布时间】:2014-01-08 21:12:27
【问题描述】:

我在 R 中有以下代码(嵌套 for 循环),非常慢。循环匹配来自两列的值。然后选取一个相应的文件并遍历该文件以找到匹配项。然后它从文件中提取该行。迭代次数可能会超过 100,000 次。请如果有人可以提供有关如何加快该过程的见解。

for(i in 1: length(Jaspar_ids_in_Network)) {
  m <- Jaspar_ids_in_Network[i]
  gene_ids <- as.character(GeneTFS$GeneIds[i])
  gene_names <- as.character(GeneTFS$Genes[i])

  print("i")
  print(i)

  for(j in 1: length(Jaspar_ids_in_Exp)) {
    l <- Jaspar_ids_in_Exp[j]
    print("j")
    print(j)

    if (m == l) {
      check <- as.matrix(read.csv(file=paste0(dirpath,listoffiles[j]),sep=",",header=FALSE))
      data_check <- data.frame(check)
      for(k in 1: nrow(data_check)) {
        gene_ids_JF <- as.character(data_check[k,3])
        genenames_JF <- as.character(data_check[k,4])

        if(gene_ids_JF == gene_ids) {
          GeneTFS$Source[i] <- as.character(data_check[k,3])
          data1 <- rbind(data1, cbind(as.character(data_check[k,3]),  
                                      as.character(data_check[k,8]), 
                                      as.character(data_check[k,9]),  
                                      as.character(data_check[k,6]), 
                                      as.character(data_check[k,7]),  
                                      as.character(data_check[k,5])))
        } else if (toupper(genenames_JF) == toupper(gene_names)) { 
          GeneTFS$Source[i] <- as.character(data_check[k,4])
          data1 <- rbind(data1, cbind(as.character(data_check[k,4]),
                                      as.character(data_check[k,5]), 
                                      as.character(data_check[k,6]), 
                                      as.character(data_check[k,7]),
                                      as.character(data_check[k,8]),
                                      as.character(data_check[k,2])))
        } else {
         # GeneTFS[i,4] <- "No Evidence"    
        }
      }
    } else {
      # GeneTFS[i,4] <- "Record Not Found"          
    }
  }  
}

【问题讨论】:

  • 首先,读入所有文件并将它们放在一个列表中(可能rbind它们在一个大data.frame中)。然后您可能可以使用merge 或使用 data.table 包及其连接。底线是你不应该在这里使用任何for 循环。但是如果你这样做了,你绝对不应该在其中增长一个对象。不能告诉你更多,因为你的例子不是reproducible
  • 我的教授对 R 的评论:永远不要使用循环!
  • 你能建议如何更换它们吗?我对 R 了解不多
  • @ExpectoPatronum 这个立场太极端了。 for 循环有位置并且非常有用(如果操作正确)。

标签: r loops for-loop match


【解决方案1】:

如果您将处理一对的逻辑提取到一个函数中,f(m,l),那么您可以将双循环替换为:

outer(Jaspar_ids_in_Network, Jaspar_ids_in_Exp, Vectorize(f))

【讨论】:

    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    相关资源
    最近更新 更多