在R中对比同行列字符串差异并生成差异物质列的技术求助
解决方案:毒理学物质列的逐行差异对比
问题根源
你手里的auto.tox和production.tox列其实是逗号拼接的单个字符串,不是拆分好的物质列表——这就是之前用setdiff、anti_join没得到预期结果的核心原因:这些函数是在对比完整字符串,而非单个独立物质。
解决思路
先把字符串拆成单个物质的向量,再逐行找出auto.tox中存在但production.tox中不存在的物质,最后把结果拼成逗号分隔的字符串(无差异时设为NA或"None")。
完整代码
先加载所需工具包:
library(tidyverse)
处理你的示例数据(修正了原数据中多余的c(),因为原数据里每个物质列是单个字符串,而非多元素向量):
df <- tribble( ~casenumber, ~auto.tox, ~production.tox, "2023-1", "Gabapentin, Alprazolam, Ethanol", "Alprazolam, Gabapentin, Ethanol", "2023-2", "Alprazolam, Fentanyl, Ethanol", "Fentanyl, Ethanol", "2023-3", "Fentanyl, Norfentanyl, 4-ANPP, Acetyl Fentanyl", "Fentanyl, Norfentanyl" ) # 核心处理流程 result <- df %>% mutate( # 拆分字符串为物质列表,同时去除每个物质前后的空格(避免空格导致误判) auto_list = str_split(auto.tox, ", ") %>% map(str_trim), prod_list = str_split(production.tox, ", ") %>% map(str_trim), # 逐行计算差异:auto有但prod没有的物质 different_substances = map2_chr(auto_list, prod_list, function(auto, prod) { diff_materials <- setdiff(auto, prod) if (length(diff_materials) == 0) { NA_character_ # 若要显示"None",直接替换为该字符串即可 } else { str_c(diff_materials, collapse = ", ") } }) ) %>% select(casenumber, different_substances) # 查看最终结果 print(result)
输出结果
# A tibble: 3 × 2 casenumber different_substances <chr> <chr> 1 2023-1 NA 2 2023-2 Alprazolam 3 2023-3 4-ANPP, Acetyl Fentanyl
关键细节
str_trim处理拆分后的物质是为了避免类似" Fentanyl"和"Fentanyl"被误判为不同物质的情况setdiff会严格匹配精确字符串,所以"Fentanyl"和"Acetyl Fentanyl"会被正确识别为不同物质- 如果希望无差异时显示
"None"而非NA,直接把代码里的NA_character_替换成"None"即可
内容的提问来源于stack exchange,提问作者GoDawgs213
相关产品推荐
相关产品推荐

