[英]Efficient way to iterate over two lists (nested loop alternative)
我有两个数据帧,SCR和SpecificSpecies。 SCR中的项目名称部分包含“特定物种”中列出的物种。
SpecificSpecies$Species
S cerevisiae
Daucus carota
SCR$MESH_HEADINGS
tetracycline CMT-3
zrg17 protein, S cerevisiae
EP4 glycoprotein, Daucus carota
我正在尝试获取SCR的子集,该子集仅包含那些没有任何匹配种类的条目。 在上述情况下,该列表仅
tetracycline CMT-3.
我学会的方法是使用嵌套循环,将SCR中的每个条目与SpecificSpecies中的每个条目进行比较。 如果找不到匹配项,请将SCR行追加到新表中:
For each row in SCR {
SpeciesNumber <- 1
match <-NULL
while ((is.null(match)) & (SpeciesNumber < length(SpecificSpecies$Species))) {
if (grepl(SpecificSpecies$Species[SpeciesNumber], SCR[row,]$MESH_HEADING)){
match <- TRUE}
SpeciesNumber <- SpeciesNumber + 1}
if ((is.null(match) & SpeciesNumber == length(SpecificSpecies$Species)) {
speciesNoMatch = rbind(speciesNoMatch, SCR[row])}
}}
但是,这非常慢,SCR中有65,000个条目,SpecificSpecies中有1500个条目。 有没有办法像这样用lapply嵌套? 还是其他一些我不熟悉的功能将对您有所帮助?
我确定这是很糟糕的代码。 我是一名医学图书馆员,有时不得不使用R进行数据分析,所以我的编程技能非常有限,但是只要我的解决方案最终可行,它通常是丑陋还是效率低下,这并不重要。 我知道一定有更好的方法可以做到这一点; 原谅我不了解可能是一个简单解决方案的事情。
我认为!(%in%)
可以解决问题:
SpecificSpecies <- data.frame(
Species = c("S cerevisiae", "Daucus carota"),
stringsAsFactors = FALSE
)
SCR <- data.frame(
MESH_HEADINGS = c("tetracycline CMT-3", "zrg17 protein", "S cerevisiae",
"EP4 glycoprotein", "Daucus carota"),
stringsAsFactors = FALSE
)
SCR[!(SCR$MESH_HEADINGS %in% SpecificSpecies$Species), , drop = FALSE]
# MESH_HEADINGS
# 1 tetracycline CMT-3
# 2 zrg17 protein
# 4 EP4 glycoprotein
, , drop = ...
不是错字。 第一个,
确保返回所有列/变量。 第二个, drop = FALSE
确保返回的结果仍然是数据帧。
好吧,我刚刚注意到你正在寻找grep
与Species
。 下面的代码应该工作:
SpecificSpecies <- data.frame(
Species = c("S cerevisiae", "Daucus carota"),
stringsAsFactors = FALSE
)
SCR <- data.frame(
MESH_HEADINGS = c("tetracycline CMT-3",
"zrg17 protein, S cerevisiae",
"EP4 glycoprotein, Daucus carota"),
stringsAsFactors = FALSE
)
matching <- lapply(SpecificSpecies$Species, function(x) {
grep(x, SCR$MESH_HEADINGS)
})
SCR[-(unlist(matching)), ]
# MESH_HEADINGS
# 1 tetracycline CMT-3
lapply()
使用匿名函数来识别模式匹配。 它遍历每个物种,并将其与每个SCR$MESH_HEADINGS
项目进行比较。 它返回匹配索引的列表。
在我们首先unlist
匹配索引以使其与子集功能兼容之后,子集( []
)会简单地删除匹配索引( -
)。
大意:
在SpecificSpecies上执行循环,因为它的行较少。 由于SCR数据帧将减少,因此需要递归执行,因此循环每次只处理较少的数据。
通常,软件包data.table
或plyr
提高性能。 这里是data.table
的解决方案
library(data.table)
SpecificSpecies <- data.frame(Species = c("S cerevisiae", "Daucus carota"),stringsAsFactors = FALSE)
SCR <- data.frame(MESH_HEADINGS = c("tetracycline CMT-3", "zrg17 protein, S cerevisiae","EP4 glycoprotein Daucus carota"),stringsAsFactors = FALSE)
dt_temp <- data.table(SCR)
for (species in SpecificSpecies$Species) {
dt_temp <- dt_temp[!grepl(species,dt_temp$MESH_HEADINGS), ]
}
dt_result <- dt_temp
dt_result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.