首页 > 解决方案 > 过滤列是否包含外部列表中的字符部分

问题描述

我有一个包含数百行和 ca.100 列的 df,以及一个包含 100 多个名称的外部列表。列表中的名称是化学品的 IUPAC 名称(例如 1,2-环己烷二甲酸二异壬酯),并且在主 df 一列与列表中的名称匹配,甚至只是部分匹配。

#dummy_df

a <- c("1,2-Cyclohexane dicarboxylic acid diisononyl ester", "Diisodecyl phthalate", "Mono-hydroxy-isononyl phthalate (OH-MiNP)",
       "Mono-isononyl phthalate (MiNP)","Bisphenol A (BPA)","4,4'-(propane-2,2-diyl)diphenol (BPA)")
b <- c(1:6)
c <- c("mg/l", "mg/l", "mg/l", "mg/l", "mg/l", "mg/l")
df <- data.frame(a,b,c, row.names = NULL)
colnames(df) <- c("ch.name", "quantity", "unit")

#external list of ch.names
IUPAC_list <- c("Cyclohegane oxylic acid", "Diisodecyl phthalate", "MiNP", 
            "BPA free uncogjugated (Bisphenol A uncoju)")

视图(df)

我需要能够使用外部列表对 df 进行子集化。问题是 df$ch.name 有时只包含列表中整个 ch.name 的一部分,反之亦然。我希望能够基本上说:

“如果 df$ch.name 中的一行与 IUPAC_list中的名称部分匹配,则将其拉出,否则删除行。”

#problem
library(tidyverse)
df_new <- df %>% filter(ch.name %in% IUPAC_list)

查看(new_df)

df_new 仅包含“邻苯二甲酸二异癸酯”,因为完美匹配但是,我需要 df_new 还包含仅部分匹配的 ch.vaules,例如“双酚 A”和“MiNP”。虽然“环己烷氧基酸”不会成为 df_new 的一部分,因为它首先不是 df 的一部分。

df_new2 <- df[grepl(paste(IUPAC_list, collapse = "|"), df$ch.name),]

查看(df_new2)

显然可以做到这一点,但还不够好,它似乎只匹配以字符串开头的化学物质,并且不搜索更复杂名称的匹配项,例如 BPA free unconjugated (Bisphenol A uncoju)。df_new2 中也存在 MiNP 和 ox-MiNP,但它们是不同的化学物质。

理想的输出应该是这样的这个

我肯定错过了一个我找不到的简单解决方案。我的问题与类似,但是,我正在 R 中尝试。

任何帮助深表感谢!

标签: rfilteringtidyverse

解决方案


推荐阅读