Регулярное выражение для сопоставления и размещения в категориях- R - PullRequest
0 голосов
/ 07 ноября 2018

у меня 3 вектора. Один содержит текст или фактические слова / предложения (текст), один вектор содержит слова, которые я хочу найти (xreg), а третий вектор (категории) содержит категории, к которым должен принадлежать каждый текст, если найдено совпадение. Вот 3 вектора:

text <- c("Sole Service here", "Freedom to Include","Freedom to Incl","Premier Reg",
"Bankhall","Bankhall","Premier Regiona","St James Play",
"Premier Regional","Health online","Premier Regional",
"Tenet","Health on line","Tenet","Nations","Woolwich",
"Premier Regional","Lifesearch","Nations","Bankhall",
"Premier Regional","Sole Service her","Lifesearch",
"Premier Regional","Sole Service","Nations",
"Sole Service","First Money service","Sole Service",
"Nations wide","Sole Service","Premier Region")

text <- tolower(text)

xreg <- c("sole","freedom","premier","bankhall","james","health","tennet",
          "nations","woolwich","life","money")

categories <- c("SS", "FD", "PR", "BK", "JM", "HT", "TT", "NT", "WW", "LF", "MY")

Я хочу выполнить поиск по вектору ' text ' на основе поисковых слов, присутствующих в векторе ' xreg '. И затем, найдя совпадение, я хочу поместить эти слова в категорию, указанную в векторе ' category '.

Так что-то вроде: ищите слово «подошва» и там, где есть указатель соответствия по индексу этого слова, или просто создайте фрейм данных со словами, а затем отдельный столбец, чтобы указать категорию, к которой оно должно принадлежать. , В случае «единственного» поместите его в категорию «SS». «свобода» - это категория «FD» и т. д.

Решение до сих пор: Я могу искать по одному для каждого ключевого слова, и оно подскажет мне индексы, в которых найдено совпадение.

 reg_func <- function(x){grep(x,text)  
    }
    reg_func("sole")
reg_func("freedom")

Это даст мне индексы для каждого подобранного слова, которые я затем смогу использовать для обновления категорий. Есть ли способ, которым я могу сделать это быстрее? вместо того, чтобы искать по одному слову за раз? Спасибо

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Объяснение функций, используемых в @Andre Elrico answer

apply(
  sapply(xreg, function(x) {grepl(x, text, ignore.case = T)}), 1, function(x) xreg[x]
)

# Apply each xreg pattern to the text vector and see if there's a match  
# result is TRUE or FALSE gives each index where there is a match
sapply(xreg, function(x) {grepl(x, text, ignore.case = T)})

Результат

      sole freedom premier bankhall james health tennet nations woolwich  life money
[1,]  TRUE   FALSE    TRUE    FALSE FALSE  FALSE  FALSE   FALSE    FALSE FALSE FALSE
[2,] FALSE    TRUE   FALSE    FALSE FALSE  FALSE  FALSE   FALSE    FALSE FALSE FALSE
[3,] FALSE    TRUE   FALSE    FALSE FALSE  FALSE  FALSE   FALSE    FALSE FALSE FALSE
[4,] FALSE   FALSE    TRUE    FALSE FALSE  FALSE  FALSE   FALSE    FALSE FALSE FALSE
[5,] FALSE   FALSE   FALSE     TRUE FALSE  FALSE  FALSE   FALSE    FALSE FALSE FALSE
[6,] FALSE   FALSE   FALSE     TRUE FALSE  FALSE  FALSE   FALSE    FALSE FALSE FALSE

# Now apply each xreg element to the TRUE's from the previous result 
# and see which element of xreg it matches with
apply(
  sapply(xreg, function(x) {grepl(x, text, ignore.case = T)}), 1, function(x) xreg[x]
)

Результат

[[1]]
[1] "sole"    "premier"

[[2]]
[1] "freedom"

[[3]]
[1] "freedom"

[[4]]
[1] "premier"

[[5]]
[1] "bankhall"

[[6]]
[1] "bankhall"

Теперь, чтобы получить категории для каждого нашего подходящего термина (регулярное выражение)

sapply(ans$xreg_m, function(x) unique(unname( categories[x] )))

что говорит:

# Take each element of xreg_m (our matched terms) and 
# see which element in the categories vector it matches with 
#  Then unname the result so you only get the category
0 голосов
/ 07 ноября 2018

Вы можете сделать это так:

данные: (изменено, чтобы иметь двойное совпадение в 1. запись и отсутствие совпадения в последней записи)

text <- c("Sole Service here, premier", "Freedom to Include","Freedom to Incl","Premier Reg",
          "Bankhall","Bankhall","Premier Regiona","St James Play",
          "Premier Regional","Health online","Premier Regional",
          "Tenet","Health on line","Tenet","Nations","Woolwich",
          "Premier Regional","Lifesearch","Nations","Bankhall",
          "Premier Regional","Sole Service her","Lifesearch",
          "Premier Regional","Sole Service","Nations",
          "Sole Service","First Money service","Sole Service",
          "Nations wide","Sole Service","Premier Region", "no match in here!!!")

#text <- tolower(text) # not needed, use ignore.case = T later

xreg <- c("sole","freedom","premier","bankhall","james","health","tennet",
          "nations","woolwich","life","money")

categories <- c("SS", "FD", "PR", "BK", "JM", "HT", "TT", "NT", "WW", "LF", "MY")

Код:

names(categories) = xreg  # create named vector

ans <- data.frame(text = I(text)) # create a data.frame where you store it all.

ans$xreg_m<-
apply(
    sapply(xreg, function(x) {grepl(x, text, ignore.case = T)}), 1, function(x) xreg[x]
      )
ans$xreg_m[!lengths(ans$xreg_m)] <- NA  # if no match is found. character(0) is returned. I want to have NA instead. character(0) has a length of 0. I'm using this knowledge to find them.

ans$categories_m<-
    sapply(ans$xreg_m, function(x) unique(unname( categories[x] )))

результат:

#                         text        xreg_m categories_m
#1  Sole Service here, premier sole, premier       SS, PR
#2          Freedom to Include       freedom           FD
#3             Freedom to Incl       freedom           FD
#4                 Premier Reg       premier           PR
#5                    Bankhall      bankhall           BK
#6                    Bankhall      bankhall           BK
#7             Premier Regiona       premier           PR
#8               St James Play         james           JM
#9            Premier Regional       premier           PR
#10              Health online        health           HT
#11           Premier Regional       premier           PR
#12                      Tenet            NA           NA
#13             Health on line        health           HT
#14                      Tenet            NA           NA
#15                    Nations       nations           NT
#16                   Woolwich      woolwich           WW
#17           Premier Regional       premier           PR
#18                 Lifesearch          life           LF
#19                    Nations       nations           NT
#20                   Bankhall      bankhall           BK
#21           Premier Regional       premier           PR
#22           Sole Service her          sole           SS
#23                 Lifesearch          life           LF
#24           Premier Regional       premier           PR
#25               Sole Service          sole           SS
#26                    Nations       nations           NT
#27               Sole Service          sole           SS
#28        First Money service         money           MY
#29               Sole Service          sole           SS
#30               Nations wide       nations           NT
#31               Sole Service          sole           SS
#32             Premier Region       premier           PR
#33        no match in here!!!            NA           NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...