减少R代码的运行时间

时间:2018-05-22 05:48:36

标签: r performance

我有两张桌子: 1. 140,000 X 2数据框由2列和140,000行文本组成(每行有几个字长)。例如,参见附件:

Table1

  1. 一个类似的表,但更小,只有1列:3,500 X 1数据框由1列和3,500行文本组成(每行一到几个字长)。例如,参见附件:
  2. Table2

    我编写了一个代码,该代码贯穿“Table1”的140,000行中的每一行,并搜索“Table2”中任何一个单词的存在,以及“complex”一词的存在,无论是上/下字符。如果代码找到匹配 - 它写在我已经预先建立的新数据框中(让我们称之为“Table3”)。

    代码是:

    Table3 <- data.frame(matrix(nrow = length(Table1$PDB), ncol = 3), stringsAsFactors=FALSE)
    names(Table3) <- c("PDB", "Description", "Ligand")
    
    for (i in 1:length(Table1$Description)) {
        for (j in 1:length(Table2$Drug)) {
    if (any(tolower(unlist(strsplit(Table1$Description[i], " "))) %in% tolower(Tabe2$Drug[j])) & any(tolower(unlist(strsplit(Table1$Description[i], " "))) %in% "complex")) {
    Table3$PDB[i] <- Tabe1$PDB[i]
    Table3$Description[i] <- Table1$Description[i]
    Table3$Ligand[i] <- Table2$Drug[j] 
      }
    print(i)
    print(j) 
    }
    }
    

    代码工作正常,但速度非常慢。根据我的计算,它需要大约20天才能完成。

    有关如何加快速度的任何建议吗?

1 个答案:

答案 0 :(得分:1)

dplyrstringr可以带来一些性能提升。首先,将Table2$Drug转换为正则表达式字符串:

library(tidyverse)
library(stringr)

drug_list <- paste(str_to_lower(Table2$Drug), collapse="|")

要显示一个有效的示例,我会将字符串"atp-gamma-s"添加到drug_list,因为Description中的EG.csv值都不包含药品名称:< / p>

drug_list <- paste(c(drug_list, "atp-gamma-s"), collapse="|")

现在将Descriptiondrug_list匹配,然后将匹配项提取到Ligand 同时检查"complex"str_detect,然后filter查看正匹配 (然后移除complex_matched列,您有Table3。)

Table3 <- Table1 %>% 
  mutate(Ligand = str_extract(str_to_lower(Description), drug_list),
         complex_matched = str_detect(str_to_lower(Description), "complex")) %>%
  filter(!is.na(Ligand), 
         complex_matched == TRUE) %>%
  select(-complex_matched)

Table3
# A tibble: 1 x 3
  PDB   Description                                  Ligand   
  <chr> <chr>                                        <chr>    
1 1XP8  Deinococcus radiodurans RecA in complex wit… atp-gamm…