【问题标题】:r - Filter rows that contain a string from a vectorr - 过滤包含来自向量的字符串的行
【发布时间】:2016-12-08 01:25:27
【问题描述】:

我正在寻找一个函数,它接受一个数据框列,检查它是否包含来自字符串向量的文本,并在匹配时对其进行过滤(包括部分文本匹配)。

例如,取如下数据框:

animal     |count
aardvark   |8
cat        |2
catfish    |6
dog        |12
dolphin    |3
penguin    |38
prairie dog|59
zebra      |17

和下面的向量

c("cat", "dog")

我想遍历“动物”列,检查值是否完全或部分与向量中的字符串之一匹配,并过滤掉不匹配的字符串。生成的数据框将是:

animal     |count
cat        |2
catfish    |6
dog        |12
prairie dog|59

谢谢!

肖恩

【问题讨论】:

  • 使用grepl: 因为df[grepl("(cat|dog)", df$animal),] 应该可以工作。

标签: r dplyr


【解决方案1】:

使用dplyr,假设您的表是df,您可以尝试以下操作:

library(dplyr)
library(stringr)
animalList <- c("cat", "dog")
filter(df, str_detect(animal, paste(animalList, collapse="|")))

我个人发现几个月后审查我的代码时使用dplyrstringr 更容易阅读。

【讨论】:

  • 我不确定这是如何工作的,因为“动物”列没有完全匹配。
  • 实际数据框的结构是什么?我们有包含玩具数据的可重现示例吗?
  • 这个问题是它只过滤完全匹配(猫和狗),而不是部分匹配(鲶鱼和草原狗)。我应该指定的。不过,我很欣赏它的外观。
  • NP。添加了部分匹配解决方案。
  • 当模式列表很长时,此解决方案效果很好。否则,将引发无效的正则表达式错误。
【解决方案2】:

我们可以使用grep

df1[grep(paste(v1, collapse="|"), df1$animal),]

或使用dplyr

df1 %>%
    filter(grepl(paste(v1, collapse="|"), animal))

【讨论】:

    【解决方案3】:

    对于大型数据集,以下 base R 方法可以比接受的答案快 15 倍。至少这是我的经验。

    代码生成一个新的数据框来存储与给定值(动物)匹配的行的子集。

    #Create placeholder data frame
    new_df <- df[0, ]
    
    #Create vector of unique values
    animals <- unique(df$animal)
    
    #Run the loop
    for (i in 1:length(animals)){
        temp <- df[df$animal==animals[i], ] 
        new_df <- rbind(new_df,temp)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-08
      • 1970-01-01
      • 2014-05-16
      • 2018-09-30
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多