R Возвращает положение слова в строке - PullRequest
1 голос
/ 01 апреля 2020

У меня есть такие данные:

data <- data.frame(
  text = c(
    "PARACETAMOL/CODEINE",
    "PSEUDOEPH/PARACET/CODEINE",
    "PARACETAMOL/CODEINE/DOXYLAMINE",
    "CODEINE & ASPIRIN",
    "CODEINE/PARACETAMOL",
    "TEST"
  ),
  stringsAsFactors = F
)

Я хочу в каждом случае возвращаться, в какой позиции находится CODEINE, т.е.

text                             position
PARACETAMOL/CODEINE                     2
PSEUDOEPH/PARACET/CODEINE               3
PARACETAMOL/CODEINE/DOXYLAMINE          2
CODEINE & ASPIRIN                       1
CODEINE/PARACETAMOL                     1
TEST                                    0

Я предпочитаю, чтобы решение DPLYR перебегало сотни строк.

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

ОБНОВЛЕНО

Я не добавил элемент, не основанный на CODEINE, оба ответа на ошибки.

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

3 голосов
/ 01 апреля 2020

Может быть, есть прямое решение для регулярных выражений, которое поможет вам достичь этого. Вот способ разбить строку на разные слова и сосчитать номер слова, где встречается "CODEINE".

library(dplyr)

data %>%
  mutate(text1 = stringr::str_extract_all(text, "\\w+"), 
         position = purrr::map_int(text1, 
                     ~max(which(.x == "CODEINE")[1], 0L, na.rm = TRUE))) %>%
  select(-text1)

#                            text position
#1            PARACETAMOL/CODEINE        2
#2      PSEUDOEPH/PARACET/CODEINE        3
#3 PARACETAMOL/CODEINE/DOXYLAMINE        2
#4              CODEINE & ASPIRIN        1
#5            CODEINE/PARACETAMOL        1
#6                           TEST        0

Используя тот же лог c в базе R, это можно сделать так:

sapply(strsplit(data$text, "/|\\&"), function(x) 
         max(which(trimws(x) == "CODEINE")[1], 0, na.rm = TRUE))
#[1] 2 3 2 1 1 0
2 голосов
/ 01 апреля 2020

Не самое простое решение, но вы можете использовать grep и strsplit. Вы можете добавить оператор ifelse для проверки отсутствия значений и заполнить 0, если это так.

В целом вы можете написать что-то вроде:

library(dplyr)

data %>% rowwise() %>% 
  mutate(Position = replace_na(ifelse(is.null(grep("CODEINE", unlist(strsplit(text,"/|\\&")))),NA,
                           grep("CODEINE", unlist(strsplit(text,"/|\\&")))),0))


Source: local data frame [7 x 2]
Groups: <by row>

# A tibble: 7 x 2
  text                           Position
  <chr>                             <dbl>
1 PARACETAMOL/CODEINE                   2
2 PSEUDOEPH/PARACET/CODEINE             3
3 PARACETAMOL/CODEINE/DOXYLAMINE        2
4 CODEINE & ASPIRIN                     1
5 CODEINE/PARACETAMOL                   1
6 PARA & CODEINE                        2
7 TEST                                  0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...