[英]R - extract elements from character string that NOT match other string
我想從一個字符串中提取不在另一個字符串中的元素。
最快的(矢量化?)方法是什么?
模擬數據:
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
我正在尋找的是一個名為new
的新變量,它保存product
中沒有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>
注意:它似乎與stringr::str_extract_all
完全相反,但此函數沒有negate
函數。
這里是一個選項,通過分裂感興趣的列strssplit
,使用setdiff
找到elemens沒有第二個。 如果沒有值,即如果length
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>
或者,如果我們需要使用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))
僅使用base和data.table ,我們並行循環遍歷兩列並使用setdiff
,然后添加 NA 並使其成為原子向量:
dt[,new:= mapply(setdiff, strsplit(product, ","), strsplit(stock, ","))]
is.na(dt$new) <- !lengths(dt$new)
dt$new <- unlist(dt$new)
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
這是純data.table代碼:
dt[,new:= mapply(setdiff, strsplit(product, ","), strsplit(stock, ","))][
lengths(new) == 0, new := NA][
, new := unlist(new)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.