【问题标题】:How to find an exact set of strings in a column of varied strings in R dataframe?如何在 R 数据框中的一列不同字符串中找到一组精确的字符串?
【发布时间】:2021-04-23 20:26:20
【问题描述】:

我希望在包含字符串的 R 数据框列中找到一组精确字符串的匹配项。

这是我的一堆参考字符串的格式,这些字符串将存储在变量splitval中:

library(gsubfn)
#Splitting each rule into its individual parameter elements
str <- strsplit(gsub("\\,\\+"," +", gsub("=>","",  gsubfn(".", list("{" = "", "}" = ""), gsub("corpsi", "+corpsi", "{dog} => {pet}")))), split='+', fixed=TRUE)
parameters <- data.frame(do.call(rbind, str)) #Creating a df of the split parameters
parameters <- data.frame(t(parameters))
parameters <- parameters[parameters$t.parameters.!="",]
parameters <- trimws(parameters, "r")

#Applying filter on all the parameters of a single rule row
splitval = strsplit(parameters[1],split=' ', fixed=TRUE)
splitval = lapply(list(splitval[[1]]), function(z){ z[z != ""]}) #Eliminating the "" instances

所以现在,splitval 具有以下值:

[[1]]
[1] "dog" "pet"

现在我的目标是过滤掉以下数据帧的所有行条目,其中字符串列的条目同时包含确切的词 dogpet

注意:它不应过滤掉包含 doganimal petsdogsareanimals and petssss

等短语的字符串

这是我的数据框:

df <- data.frame(Srno = 1:5, Description = c("dog is my pet", "doganimal pets country", "my pet is my dog", "dogsareanimals and petssss", "a pet dog is great"))

看起来像这样:

因此,我只需要提取中的第 1,3 和 5 行,因为只有这些行包含专有字符串“dog”和“pet”(没有特定顺序)

但是当我使用以下代码时,我得到了数据框的所有行,因为所有字符串都包含两个引用关键字 - grep 没有达到预期目的。

extract_df <- df[(grep(splitval[[1]][1], df$Description)),]
  for(k in 2:length(splitval[[1]]))
  {
    extract_df  <- extract_df[(grep(splitval[[1]][k], df$Description)),]
  }

那么任何人都可以帮助我在输出提取的数据框中仅获取第 1,3 和 5 行吗?

【问题讨论】:

  • df[grepl("^(?=.*\\bpet\\b)(?=.*\\dog\\b)", df$Description, perl=TRUE)]?
  • @WiktorStribiżew 有语法错误吗?它不会导致空数据框。虽然我想我可以预测你在这里尝试使用的逻辑,但我不想明确地硬编码 2 个感兴趣的字符串 - 我想以变量本身的形式保存它,即 splitval[ [1]][1] & splitval[[1]][2]

标签: r regex string dataframe string-matching


【解决方案1】:

假设splitval 中可以包含许多单词,并且并不总是包含两个固定单词,您可以为每个单词拆分字符串并选择具有all 中的单词vec 的行。

在基础 R 中,您可以这样做:

vec <- splitval[[1]]
#For this case
#vec <- c("dog", "pet")

subset(df, sapply(strsplit(df$Description, '\\s+'), function(x) all(vec %in% x)))

#  Srno        Description
#1    1      dog is my pet
#3    3   my pet is my dog
#5    5 a pet dog is great

使用tidyverse

library(tidyverse)
df %>% filter(map_lgl(str_split(df$Description, '\\s+'), ~all(vec %in% .x)))

【讨论】:

    猜你喜欢
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多