我有两张桌子: 1. 140,000 X 2数据框由2列和140,000行文本组成(每行有几个字长)。例如,参见附件:
我编写了一个代码,该代码贯穿“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天才能完成。
有关如何加快速度的任何建议吗?
答案 0 :(得分:1)
dplyr
和stringr
可以带来一些性能提升。首先,将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="|")
现在将Description
与drug_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…