R 匹配代码在O(n2)处运行。你能推荐运行更接近O(n)的替代代码吗?
我有一个大型数据框,其中有一列(字符)物种名称,名为hit.match。hit.match可以包含一个物种名称,或超过20个物种名称,由管道字符“|”分隔。我需要快速代码来检查与hit.match中单个物种的匹配。我当前的代码按O(n2)(n平方)缩放,其中n是输入记录的数量。我需要它扩展得更快,更接近O(n)R 匹配代码在O(n2)处运行。你能推荐运行更接近O(n)的替代代码吗?,r,R,我有一个大型数据框,其中有一列(字符)物种名称,名为hit.match。hit.match可以包含一个物种名称,或超过20个物种名称,由管道字符“|”分隔。我需要快速代码来检查与hit.match中单个物种的匹配。我当前的代码按O(n2)(n平方)缩放,其中n是输入记录的数量。我需要它扩展得更快,更接近O(n) ###Function matched在输入df的hit.match中查找,并在输入物种列表match.list中返回优先排序的物种之一,该物种按优先级顺序与hit.match匹配。如果
###Function matched在输入df的hit.match中查找,并在输入物种列表match.list中返回优先排序的物种之一,该物种按优先级顺序与hit.match匹配。如果未找到任何优先排序的物种,则返回原始的hit.match
#输入是一个df和一个物种学名列表(属物种),本地称为match.list
#输出是一个df,hit.match替换为优先物种名称或保留原始hit.match
匹配我们可以在“|”
上拆分字符串,通过粘贴匹配来创建一个模式。如果模式与hit.match
中的任何元素匹配,我们将返回第一个匹配项,否则将再次返回hit.match
pat <- paste0(match.list, collapse = "|")
sapply(strsplit(df$hit.match, "\\|"), function(x) {
inds <- grep(pat, x)
if (length(inds) > 0) trimws(x[inds[1L]])
else paste0(x, collapse = "|")
})
#[1] "Nomina nudum" "Nomina nudum1" "Nomina nudum" "Nomina nudum1" "Nomina nudum2"
pat谢谢你,Ronak!你的想法非常聪明,你的代码极大地提高了我对R的理解。您的建议非常有效,根据我的计时处理时间,从10个文件到总计1300万条记录,运行速度为O(n)。每个文件快4个小时。
pat <- paste0(match.list, collapse = "|")
sapply(strsplit(df$hit.match, "\\|"), function(x) {
inds <- grep(pat, x)
if (length(inds) > 0) trimws(x[inds[1L]])
else paste0(x, collapse = "|")
})
#[1] "Nomina nudum" "Nomina nudum1" "Nomina nudum" "Nomina nudum1" "Nomina nudum2"
df <- data.frame(hit.match = c("Nomina nudum", " Nomina nudum1 | Nomina nudum2",
" Nomina nudum | Nomina nudum1 | Nomina nudum2", " Nomina nudum1",
" Nomina nudum2"), stringsAsFactors = FALSE)
match.list <- c("Nomina nudum", " Nomina nudum1 ", " Nomina nudum2")