найти соответствие для строки в векторе регулярных выражений - PullRequest
4 голосов
/ 11 апреля 2019

Предположим, у меня есть символьный вектор

vals <- c("hello","goodbye","junk")

и вектор целей регулярных выражений

targets <- c("(hello|goodbye)","^j","other")

(Я хочу указать, что каждый элемент в vals соответствует ровно одному элементу в targets). Существует ли существующий, эффективный / компактный / векторизованный способ найти индекс соответствия каждого элемента в vals в targets? (match не работает: он соответствует таблице строк, а не регулярным выражениям.) Таким образом, желаемый вывод c(1,1,2) для этого примера. Приветствуются решения Base-R или Tidyverse / stringr.

Ответы [ 3 ]

3 голосов
/ 11 апреля 2019

Один из подходов состоит в том, чтобы установить имена list с последовательностью и stack в двух столбце data.frame.Элементы NULL будут удалены с помощью stack.Теперь мы извлекаем второй столбец, чтобы получить индекс list

as.integer(stack(setNames(m, seq_along(m)))[,2])
#[1] 1 1 2

ПРИМЕЧАНИЕ. Здесь m - это вывод list индекса @ BenBolker из grep output


Или используя tidyverse

library(tidyverse)
crossing(targets, vals) %>%
    mutate(ind = group_indices(., targets)) %>%
    filter(str_detect(vals, targets)) %>%
    pull(ind)
#[1] 1 1 2
2 голосов
/ 11 апреля 2019

Лучший способ, которым я могу придумать, это сделать: инвертировать соответствие, то есть: перебрать цели, а затем заполнить совпадения в векторе, соответствующем значениям.

## find positions in `vals` that match each target
m <- lapply(targets,grep,x=vals)
## set up response vector
res <- rep(NA,length(vals))
## fill in matching positions for each target
for (i in seq_along(m)) {
    res[m[[i]]] <- i
}
0 голосов
/ 15 апреля 2019

Используя str_detect в stringr, зациклите каждое значение, чтобы найти целевой индекс.

library(stringr)

# Data
vals <- c("hello","goodbye","junk")
targets <- c("(hello|goodbye)","^j","other")

# create empty vector to assign matched value later
v  <- c()

for (i in 1:length(vals)){

  # value to be looked up against target
  stg_i <- vals[i]

  # min to get first matched target
  stg_v <- min(which(str_detect(stg_i, targets)))

  # update the value in vector with matched one
  v[i] <- stg_v

}

v
[1] 1 1 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...