Reputation: 189
I have 2 data frames:
data1 <- data.frame(names = c("ALBERT | ALBERTIS 2",
"PIERRE | JEAN | ALBERT",
"ALBERTOS"))
data2 <- data.frame(names_search = c("ALBERT", "PIERRE"))
I want to know that each whole WORD of data2
is present in data1
. A new column in data1
will contain those elements matched.
So I want a result like:
data3 <- data.frame(names = c("ALBERT | ALBERTOS | ALBERT 2",
"ALBERT | ALBERTOS | ALBE 2",
"PIERRE | PIERRE 2 | PIERRE_SECOND | PIERRE_SECOND 2"),
names_search = c("ALBERT", "ALBERT | PIERRE", ""))
Do you have any idea how to do this?
I tried this in double loop (hope you can give a better way) but it failed.
for( i in 1:nrow(data1)){
result <- ""
for(j in 1: nrow(data2)){
present <- grepl(eval(parse(text = paste0('\\<',data2$names_search[j],'\\>'))), data1$names[i], fixed = T)
# I check if the whole word data[j] is present in data1[i]
if(present ==T){
result <- paste(result, data2$names_search[j], sep= "|")
}
}
data1$names_search[i] <- result
}
Upvotes: 2
Views: 39
Reputation: 72828
We can split the strings (i.e. each line) at " | "
using strsplit
; thereafter we just subset each iteration with the match vector of data2
if it's %in%
side. At the end, the if
handles the case when there is no match, the else
paste
s the result into the desired form.
data1 <- transform(
data1,
names_search=sapply(strsplit(as.character(data1$names), " | ", fixed=TRUE), function(x) {
out <- x[x %in% data2$names_search]
if (length(out) == 0) NA_character_
else paste(out, collapse=" | ")
}))
data1
# names names_search
# 1 ALBERT | ALBERTIS 2 ALBERTIS 2
# 2 PIERRE | JEAN | ALBERT PIERRE
# 3 ALBERTOS <NA>
Data
data1 <- structure(list(names = structure(c(1L, 3L, 2L), .Label = c("ALBERT | ALBERTIS 2",
"ALBERTOS", "PIERRE | JEAN | ALBERT"), class = "factor")), class = "data.frame", row.names = c(NA,
-3L))
data2 <- structure(list(names_search = structure(1:2, .Label = c("ALBERTIS 2",
"PIERRE"), class = "factor")), class = "data.frame", row.names = c(NA,
-2L))
Upvotes: 1