R-从字符串中提取与其他字符串不匹配的元素

wak*_*ake 1 regex r stringr data.table

我想从一个字符串中提取不在另一字符串中的元素。

什么是最快的(向量化?)方法?

模拟数据:

library(data.table)
dt <- data.table(id = c("A", "B", "C", "D"),
             product= c("1", "1,2", "1,2,3", "4"),
             stock= c("2, 3", "1,2", "1,2", "4"))

> dt
   id product stock
1:  A       1  2, 3
2:  B     1,2   1,2
3:  C   1,2,3   1,2
4:  D       4     4
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是一个名为的新变量new,该变量包含productnot中的元素stock

> dt
   id product stock  new
1:  A       1  2, 3    1
2:  B     1,2   1,2 <NA>
3:  C   1,2,3   1,2    3
4:  D       4     4 <NA>
Run Code Online (Sandbox Code Playgroud)

注意:似乎与完全相反stringr::str_extract_all,但是此函数没有negate功能。

akr*_*run 7

这是通过用分割感兴趣的列的一种选择strssplit,用于setdiff查找不在第二列中的元素。如果没有值,即lengthiss 0,则返回NA

f1 <- function(x, y) {
    x1 <- setdiff(x, y)
   if(!length(x1)) NA_character_ else x1
 }

dt[, new := do.call(Map, c(f = f1,
    unname(lapply(.SD, strsplit, ",")))), .SDcols = 2:3]
dt
#   id product stock  new
#1:  A       1  2, 3    1
#2:  B     1,2   1,2 <NA>
#3:  C   1,2,3   1,2    3
#4:  D       4     4 <NA>
Run Code Online (Sandbox Code Playgroud)

或者,如果我们需要使用str_extract_all,tidyverse选项将是

library(tidyverse)
dt %>% 
   mutate_at(2:3, list(newvar = ~ str_extract_all(., '\\d+'))) %>%  
   transmute(id, product, stock, new = map2(product_newvar, stock_newvar, f1))
Run Code Online (Sandbox Code Playgroud)