Точное соответствие текста со столбцом dataframe в r - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть вектор слов в R:

words = c("Awesome","Loss","Good","Bad")

И у меня есть следующий фрейм данных в R:

df <- data.frame(ID = c(1,2,3),
                 Response = c("Today is an awesome day", 
                              "Yesterday was a bad day,but today it is good",
                              "I have losses today"))

То, что я хочу сделать, это слова, которые точно совпадают в столбце Ответ, должны быть извлечены и вставлены в новый столбец в кадре Окончательный результат должен выглядеть следующим образом

ID           Response                        Match          
1            Today is an awesome day        Awesome           
2            Yesterday was a bad day        Bad,Good           
             ,but today it is good      
3            I have losses today            NA

Я использовал следующий код:

извлечь список подходящих слов

x <- sapply(words, function(x) grepl(tolower(x), tolower(df$Response)))

вставить соответствующие слова вместе

df$Words <- apply(x, 1, function(i) paste0(names(i)[i], collapse = ","))

Но это обеспечивает совпадение, но не точное. Пожалуйста, помогите.

Ответы [ 3 ]

0 голосов
/ 11 апреля 2020

Мы можем использовать str_extract_all

library(stringr)
library(dplyr)
library(purrr)
df %>%
    mutate(Words = map_chr(str_extract_all(Response, str_c("
       (?i)\\b(", str_c(words, collapse="|"), ")\\b")), toString))
#   ID                                     Response     Words
#1  1                      Today is an awesome day   awesome
#2  2 Yesterday was a bad day,but today it is good bad, good
#3  3                          I have losses today          

данные

words <- c("Awesome","Loss","Good","Bad")
0 голосов
/ 11 апреля 2020

Измените первую функцию *apply на двухстрочную функцию. Если регулярное выражение становится "\\bword\\b", тогда оно захватывает слово, окруженное границами.

x <- sapply(words, function(x) {
  y <- paste0("\\b", x, "\\b")
  grepl(tolower(y), tolower(df$Response))
})

Теперь запустите второй apply, как указано в вопросе.

df$Words <- apply(x, 1, function(i) paste0(names(i)[i], collapse = ","))

df
#  ID                                     Response    Words
#1  1                      Today is an awesome day  Awesome
#2  2 Yesterday was a bad day,but today it is good Good,Bad
#3  3                          I have losses today       

Что касается NA s, я буду использовать функцию is.na<-.

is.na(df$Words) <- df$Words == ""

Данные.

df <- read.table(text = "
ID           Response
1            'Today is an awesome day'
2            'Yesterday was a bad day,but today it is good'
3            'I have losses today'
", header = TRUE)

words <- c("Awesome","Loss","Good","Bad")
0 голосов
/ 11 апреля 2020

Если вы используете якоря в своем векторе words, вы обеспечите точное совпадение: ^ утверждает, что вы в начале, $, что вы в конце слова. Итак:

words = c("Awesome","^Loss$","Good","Bad")

Затем используйте ваш код:

x <- sapply(words, function(x) grepl(tolower(x), tolower(df$Response)))
df$Words <- apply(x, 1, function(i) paste0(names(i)[i], collapse = ","))

, который дает:

> df
  ID                                     Response    Words
1  1                      Today is an awesome day  Awesome
2  2 Yesterday was a bad day,but today it is good Good,Bad
3  3                          I have losses today  

Чтобы превратить пропуски в NA:

df$Words[df$Words == ""] <- NA
...