预处理/格式化数据

Pre-Processing / Formatting Data

我在 R 中有两个向量:

     list1 <- c("ABCDEF", "FEDCBA", "AA-BB-CCCC", "ABCDEFGH-IJK", "ZZZZ")
     
     list2 <- c("ABCDEF", "FEDCBA:XA",   
   "AA-BB-CCCC-01","AA-BB-CCCC-21:ABC", "ABCDEFGH-IJK-1X",   
   "AKDWXFE-XXY")

我想比较两个列表 -- list1 是 'correct' 列表。如果list1中的一项没有出现在list2中,则打印出'Add [item in list1]';如果 list2 中的项目不在 list1 中,则打印出 'delete [item in list 2]'。我想找到部分匹配项。例如,列表 1 具有 'FEDCBA',列表 2 具有“FEDCBA:XA”——这将是可接受的部分匹配....与列表 2 具有 AA-BB-CCCC-21:ABC 而列表 1 具有 AA 相同-BB-CCCC(这也是可接受的部分匹配)。

对我来说这看起来像是作业,但是好吧,让我们把它作为一个教学时刻。

首先,让我们找出list1 的哪些元素在list2 中匹配。为此,我们将使用 grepl,其中 return 是一个逻辑向量,其中每个元素都有一个 TRUE/FALSE 值。

library(tidyverse)
                            
list1_has_match <- map_lgl(list1, ~ any(grepl(., list2)))
msg <- sprintf("Add [%s]", list1[ !list1_has_match ])

在上面的代码中,我使用 map_lgl 到 运行 list1 的每个元素的 any(grepl(...)) 表达式和 return 一个逻辑向量。该向量中具有 FALSE 值的任何元素不存在于 list2 中,应添加。

接下来,我们做同样的事情——反过来。但是,我们仍然必须使用 list1 的元素作为模式。这就是为什么下一点变得有点复杂的原因。在 map_dfr 中的每个调用中,我们都会生成一个与 list1 的一个元素相对应的命名向量。但是,由于我们使用 map_dfr,因此这些向量中的每一个都将被视为数据框中的一行。因此,结果的列将对应于 list2 的元素。

map1 <- map_dfr(list1, ~ set_names(grepl(., list2), list2))

list2_has_match <- map_lgl(map1, any)
msg <- c(msg, 
         sprintf("delete [%s]", list2[ !list2_has_match ]))

现在打印消息

cat(msg, sep="\n")