将一列中的文本与另一列匹配(vlookup + like)
Match text from one column with another column (vlookup + like)
我正在尝试执行 2 列的匹配但没有成功。我有一个 DF1
,有 2 列,Id
和 JSON
。在第二个 DF2
中,我有一列在每一行中都有一个模式要匹配 DF1$json
(类似于 vlookup + like 函数)。
作为输出,我想得到 DF1$Id
但只有 DF2
中的任何一个与 DF1$json
匹配。
我尝试了一些与 str_detect
的组合,但它不适用于非向量值。也许 grep
或 stringr
函数有一些技巧?
例如:
str_detect(DF1$json, fixed(DF2[1,1], ignore_case = TRUE))
这是否给了您预期的结果:
my_df <- data.frame("id" = c("AA", "BB", "CC", "DD"),
"json" = c("{x:y:z};{m:z:v}", "{c:y:z};{d:z:v}", "{t:y:z};{m:z:v}", "{u:y:z};{m:z:v}"),
"pattern" = c("m:z:v", "t:y:z", "m:z:v", "t"),
stringsAsFactors = FALSE)
my_f <- function(x) {
my_var <- paste(grep(pattern = my_df[x, "pattern"], x = my_df$json), collapse = " ")
return (my_var)
}
my_df$Value <- lapply(1:nrow(my_df), my_f)
df1 <- data.frame(
Id = c("AA", "BB", "CC", "DD"),
json = c("{xxx:yyy:zzz};{mmm:zzz:vvv}", "{ccc:yyy:zzz};{ddd:zzz:vvv}", "{ttt:yyy:zzz};{mmm:zzz:vvv}", "{uuu:yyy:zzz};{mmm:zzz:vvv}")
)
matches <- c("mmm:zzz:vvv", "mmm:yyy:zzz")
library(stringr) # needed for str_extract_all()
解决方案使用data.table
library(data.table)
setDT(df1)
df1[, match := any(str_extract_all(json, "(?<=\{).+?(?=\})")[[1]] %in% matches), by = Id]
df1[match == T, .(Id)]
使用dplyr的解决方案
library(dplyr)
df1 %>%
group_by(Id) %>%
mutate(match = any(str_extract_all(json, "(?<=\{).+?(?=\})")[[1]] %in% matches)) %>%
filter(match == T) %>%
select(Id)
或者直接filter()
df1 %>%
group_by(Id) %>%
filter(any(str_extract_all(json, "(?<=\{).+?(?=\})")[[1]] %in% matches)) %>%
select(Id)
两种方法的输出
Id
1: AA
2: CC
3: DD
我正在尝试执行 2 列的匹配但没有成功。我有一个 DF1
,有 2 列,Id
和 JSON
。在第二个 DF2
中,我有一列在每一行中都有一个模式要匹配 DF1$json
(类似于 vlookup + like 函数)。
作为输出,我想得到 DF1$Id
但只有 DF2
中的任何一个与 DF1$json
匹配。
我尝试了一些与 str_detect
的组合,但它不适用于非向量值。也许 grep
或 stringr
函数有一些技巧?
例如:
str_detect(DF1$json, fixed(DF2[1,1], ignore_case = TRUE))
这是否给了您预期的结果:
my_df <- data.frame("id" = c("AA", "BB", "CC", "DD"),
"json" = c("{x:y:z};{m:z:v}", "{c:y:z};{d:z:v}", "{t:y:z};{m:z:v}", "{u:y:z};{m:z:v}"),
"pattern" = c("m:z:v", "t:y:z", "m:z:v", "t"),
stringsAsFactors = FALSE)
my_f <- function(x) {
my_var <- paste(grep(pattern = my_df[x, "pattern"], x = my_df$json), collapse = " ")
return (my_var)
}
my_df$Value <- lapply(1:nrow(my_df), my_f)
df1 <- data.frame(
Id = c("AA", "BB", "CC", "DD"),
json = c("{xxx:yyy:zzz};{mmm:zzz:vvv}", "{ccc:yyy:zzz};{ddd:zzz:vvv}", "{ttt:yyy:zzz};{mmm:zzz:vvv}", "{uuu:yyy:zzz};{mmm:zzz:vvv}")
)
matches <- c("mmm:zzz:vvv", "mmm:yyy:zzz")
library(stringr) # needed for str_extract_all()
解决方案使用data.table
library(data.table)
setDT(df1)
df1[, match := any(str_extract_all(json, "(?<=\{).+?(?=\})")[[1]] %in% matches), by = Id]
df1[match == T, .(Id)]
使用dplyr的解决方案
library(dplyr)
df1 %>%
group_by(Id) %>%
mutate(match = any(str_extract_all(json, "(?<=\{).+?(?=\})")[[1]] %in% matches)) %>%
filter(match == T) %>%
select(Id)
或者直接filter()
df1 %>%
group_by(Id) %>%
filter(any(str_extract_all(json, "(?<=\{).+?(?=\})")[[1]] %in% matches)) %>%
select(Id)
两种方法的输出
Id
1: AA
2: CC
3: DD