我有两个数据框,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进行数据分析,所以我的编程技能非常有限,但是如果我的解决方案很难或效率低下,只要它们最终起作用,那通常并不重要。 。我知道必须有更好的方法来做到这一点;原谅我不知道可能是一个简单的解决方案。
答案 0 :(得分:0)
我认为!(%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
),以使其与子集函数兼容。 / p>
答案 1 :(得分:0)
主要想法:
在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