R 模糊匹配词的返回向量

R 模糊匹配词的返回向量,r,agrep,R,Agrep,我正在使用agrepl()通过模糊匹配单词来过滤data.table。这对我来说效果很好,使用类似这样的东西: library(data.table) data <- as.data.table(iris) pattern <- "setosh" dt <- data[, lapply(.SD, function(x) agrepl(paste0("\\b(", pattern, ")\\b"), x, fixed = FALSE, ignore.case = TRUE

我正在使用
agrepl()
通过模糊匹配单词来过滤data.table。这对我来说效果很好,使用类似这样的东西:

 library(data.table)
 data <- as.data.table(iris)
 pattern <- "setosh"
 dt <- data[, lapply(.SD, function(x) agrepl(paste0("\\b(", pattern, ")\\b"), x, fixed = FALSE, ignore.case = TRUE))] 
 data<- data[rowSums(dt) > 0]
 head(data)

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:          5.1         3.5          1.4         0.2  setosa
2:          4.9         3.0          1.4         0.2  setosa
3:          4.7         3.2          1.3         0.2  setosa
4:          4.6         3.1          1.5         0.2  setosa
5:          5.0         3.6          1.4         0.2  setosa
6:          5.4         3.9          1.7         0.4  setosa
您可以看到,我没有得到向量中的结果,结果包括完整值“setosh species”,而不仅仅是“setosh”(匹配的部分)


希望这更有帮助

只需使用agrep的输出作为正在进行grepping的字符向量的索引即可

vec <- c("setosh", "setosz", "sethosz", "etosh", "ethos", "seosh")
idx <- agrep("setosh", vec) # grepl works as well
vec[idx]
编辑:好的,但是如果我们只希望得到匹配的字符串呢?不是全部,只是匹配的部分?然后我们就有了一点乐趣,因为grep/grepl和agrep/agrepl不是这样工作的。幸运的是,这里有
aregexec
函数

vec <- c("setosh is my name", "setosz", "sethosz who", 
         "what etosh", "ethos", "seosh", "funk setos brother")
matches <- aregexec("setosh", vec)
我们可以使用这些数字来提取匹配的字符串

library(purrr)
starts <- unlist(matches)
ends <- starts - 1 + map_int(matches, ~ attr(., "match.length"))
res <- substr(vec, starts, ends)
res[ starts < 0 ] <- NA
有了res,我们可以做一些事情。我们可以删除NA并查看唯一值:

res <- res[ !is.na(res) ]
unique(res)
最终编辑:OP选择的示例似乎与他们的想法不完全一致。因此,我们将再举一个例子

vec <- c("setosh is my name", "setosz", "sethosz who", 
         "what etosh", "ethos", "seosh", "funk setos brother")
data <- data.table(matrix(sample(vec, 100, replace=T), ncol=5))
好的,但如果您只想获得唯一的匹配,我们可以进一步简化:

vec <- unique(vec)

如果我理解正确,你真的只想从字符串中提取模糊匹配。听起来在使用数据帧和返回向量时也存在一些问题,但我认为一旦成功提取了匹配的子字符串,它就会变得简单得多

我将使用以下玩具数据:

库(data.table)
种子集(123)

我不太清楚你在问什么。如果你创建了一个字符向量
s,谢谢gersht。这不太管用,因为我只想要模糊匹配的单词,而不是完整的值。当搜索较长的文本字段时,这一点更为明显。我在下面给出了一个例子来回应一月的回答。坦白地说,我仍然不明白您试图用数据表实现什么。您说要筛选行,但您正在对数据表的列进行操作。因此,您在列上循环,并且对于每个列,您尝试将模式与列相匹配。但是前四列包含数字,因此这些都不匹配:这就是为什么您会收到四条错误消息(每列一条)。第五种方法终于奏效了,你得到了data.table,一个data.table应该得到的东西。停止使用data.table或学习如何使用它;-)你想要一个字符向量,很好。为什么不将agrep或aregexec应用于感兴趣的列?例如,使用我下面的方法?这就是你现在想要的吗?例如:
aregexec(“setosh”,data$Species)
然后处理匹配以获得子字符串。我不是在尝试筛选行,我从来没有说过这一点。我不知道怎么说得更清楚。我想要data.table中任何地方出现的模糊匹配的单词向量。我完全理解为什么会有这些错误——我不是在问这个问题,我只是把它们留在里面,这样人们就不会认为我提供了不完整的信息。我使用这种方法的原因是搜索整个数据集,而不仅仅是一列,因为与此示例不同,在我的数据中,匹配可能发生在任何地方。谢谢,我可以看到这种方法有效,但我无法将其应用于数据集-我将更新我的问题,使其更具体。实际上,这对我想要的也不太有效,因为它不只是隔离模糊匹配值。使用
vec-Ah。我懂了。我不明白这是如何帮助您选择列的(因为如果列名是“setosa species”,那么您需要全部内容),但我明白了:您需要的是实际的匹配,而不是匹配的字符串。不幸的是,这不是grep/grepl/agrep/agrepl的工作方式。我不想选择列-我在顶部包含的代码已经做到了这一点,它只是我如何使用
agrepl()
的一个示例。但在搜索匹配时,我处理的是数据集,而不是单个向量。我并不特别在意这样做的方式是否与grep家族中的某些东西有关(例如,我发现用于精确匹配的方式使用
str_match()
from
stringr
),我只是在寻找一种有效的方式!是的,但是它应该做什么呢!我不知道。是否要筛选列?是否要获取匹配向量?是否要筛选行?您上面的代码不正确(您grep了所有列,这是故意的吗?),所以很难知道您想要什么。
vec <- data$Species
matches <- aregexec("setosh", vec)
starts <- unlist(matches)
ends <- starts - 1 + map_int(matches, ~ attr(., "match.length"))
res <- substr(vec, starts, ends)
res[ starts < 0 ] <- NA
res <- res[ !is.na(res) ]
unique(res)
[1] "setosa" "setosh"
vec <- c("setosh is my name", "setosz", "sethosz who", 
         "what etosh", "ethos", "seosh", "funk setos brother")
data <- data.table(matrix(sample(vec, 100, replace=T), ncol=5))
vec <- unlist(data)
vec <- unique(vec)
[1] "setosh" "setosz" "setos " "seosh"  " etosh"
                 V1               V2               V3
1: blah setosh blah             bloh             bloh
2:             bloh blah setosh blah           setosa
3: blah setosh blah         bluh sep      blah seposa
4:      blah seposa  bleh versicolor blah setosh blah
5:      blah seposa             bloh         bluh sep
       V1     V2     V3
1: setosh              
2:        setosh setosa
3: setosh        seposa
4: seposa        setosh
5: seposa