【问题标题】:Subset a df using partial match with multiple criteria使用与多个条件的部分匹配对 df 进行子集
【发布时间】:2018-07-20 13:27:32
【问题描述】:

这是数据集:

company <- c("Coca-Cola Inc.", "DF, CocaCola", 
         "COCA-COLA", "PepsiCo Inc.", "Beverages Distribution")
brand  <- c("Coca-Cola Zero","N/A", "Coca-Cola", "Pepsi", "soft drink")
vol  <- c("2456","1653", "19", "2766", "167")
data   <-data.frame(company, brand, vol)
data

结果:

                 company             brand    vol
1         Coca-Cola Inc.    Coca-Cola Zero   2456
2           DF, CocaCola               N/A   1653
3              COCA-COLA          CocaCola     19
4           PepsiCo Inc.             Pepsi   2766
5 Beverages Distribution        soft drink    167

假设这是按品牌进口的数量。

任务是对数据框进行 SUBSET 以仅查看与可口可乐相关的观察结果,而不是任何其他品牌。

  • 问题在于可口可乐的编写方式多种多样。
  • 另外,我们知道饮料分销公司只进口 可口可乐,尽管上表中没有标明。

我们需要将 COMPANY 和 BRAND 变量与标准(键)列表进行部分匹配:

company_key <- c("coca-", "cocacola", "coca cola", "beverages distribution")
brand_key <- c("coca-", "cocacola", "coca cola")

我正在努力执行这个想法:

如果品牌部分匹配来自brand_key向量的任何键或公司部分匹配来自company_key的任何键

所以,只留下以下几行:

品牌观察部分匹配“coca-”或“cocacola”或“coca cola”)

公司观察部分匹配“可口可乐”或“可口可乐”或“可口可乐”或“饮料分布”)

注意:需要不区分大小写

理想的输出:

                 company             brand    vol
1         Coca-Cola Inc.    Coca-Cola Zero   2456
2           DF, CocaCola               N/A   1653
3              COCA-COLA          CocaCola     19
4 Beverages Distribution        soft drink    167

有什么想法吗?在此先感谢:)

【问题讨论】:

  • 对于部分匹配使用grepl 用于在ignore.case=T 中构建的ingore 案例使用或在您的正则表达式模式中添加"(?i)"。使用 pastecollapse="|" 作为您的键向量。
  • @Parfait 抱歉措辞错误。这正是我需要的,帮助我弄清楚我手头的任务

标签: r subset string-matching


【解决方案1】:

使用正则表达式及其|(或)运算符。参数ignore.case 处理这种情况。

index <- grepl(paste0(company_key, collapse = "|"), data$company, ignore.case = TRUE) |
    grepl(paste0(brand_key, collapse = "|"), data$company, ignore.case = TRUE)

data[index,]  

#                 company          brand  vol
#1         Coca-Cola Inc. Coca-Cola Zero 2456
#2           DF, CocaCola            N/A 1653
#3              COCA-COLA      Coca-Cola   19
#5 Beverages Distribution     soft drink  167

【讨论】:

  • 非常好。请参阅我对忽略案例的评论。这可以改进。
  • 改进意味着更通用。如果您的密钥包含单个大写字母,则此解决方案将不再有效。
  • @AndreElrico 是的,谢谢!我想通了。一个更通用的解决方案是添加 ignore.case 标准然后
【解决方案2】:

考虑到coca 后面可以跟一个破折号或前面有可选空格的可乐。我将两列粘贴在一起以进行 coca 搜索,并对 Beverage Distribution 进行不同的测试

data[grepl("coca-|(\\s*cola)", paste(data[,1], data[,2]), ignore.case = T) |
       grepl("Beverages Distribution",data[,1]),]
#                  company          brand  vol
# 1         Coca-Cola Inc. Coca-Cola Zero 2456
# 2           DF, CocaCola            N/A 1653
# 3              COCA-COLA      Coca-Cola   19
# 5 Beverages Distribution     soft drink  167

如果Beverage Distribution 只能完全匹配,您可能需要将第二部分更改为data[,1] == "Beverages Distribution"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    相关资源
    最近更新 更多