繁体   English   中英

迭代两个列表的有效方法(嵌套循环替代)

[英]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确保返回的结果仍然是数据帧。

更正

好吧,我刚刚注意到你正在寻找grepSpecies 下面的代码应该工作:

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.tableplyr提高性能。 这里是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM