совпадение строк: слова + символы - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь найти кадр данных, чтобы найти строку, где я сделал объект из столбца, заполненного заметками.

Как пример:

Я ищу любую строку с заметками, которые могут соответствовать

mph_words<-c(">10", "> 10", ">20", "> 20")

И строка кода может напоминать:

> lc_notes[1703]
[1] "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph."

Как вы можете видеть, некоторые заметки имеют пробелы между "<" или ">" и числом, поэтому использование strsplit для поиска не будет идеальным, потому что мне нужно сохранить "<" / ">" с число.

Я пробовал

> mph_words %in% lc_notes[2000]
[1] FALSE FALSE FALSE FALSE

> pmatch(mph_words, lc_notes[1703])
[1] NA NA NA NA

grepl(lc_notes[1703],mph_words)
[1] FALSE FALSE FALSE FALSE

> str_detect(mph_words,lc_notes[1703])
[1] FALSE FALSE FALSE FALSE

> for (word in 1:length(mph_words)){
+   print(str_extract(mph_words[word],lc_notes[1703]))
+ }
[1] NA
[1] NA
[1] NA
[1] NA

и я не уверен, что попробовать дальше. Если это выражение регулярного выражения, не могли бы вы объяснить это в своем ответе? Я пытаюсь понять регулярные выражения лучше.

Редактировать Я пытаюсь распечатать строки, в которых есть один из символов в mph_words. Таким образом, код будет искать каждую строку в моем lc_notes и печатать строку 1703.

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 14 января 2019

Вот способ использования strsplit и lapply

# standardize (get rid of white spaces between <,> and digits in mph_words
mph_words <- unique(gsub('([<>])\\s{0,}(\\d+)', '\\1\\2', mph_words, perl = TRUE))        
# match 
check <- lapply(1:length(lc_notes), 
                function (k) any(mph_words %in% unlist(strsplit(lc_notes[k], ' '))))
check
# [[1]]
# [1] TRUE

# [[2]]
# [1] TRUE

# [[3]]
# [1] FALSE

# Finally printing the indices with a match
which(unlist(check))
# [1] 1 2

с данными

mph_words <- c(">10", "> 10", ">20", "> 20")  
lc_notes <- "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph."
lc_notes <- c(lc_notes, 'test >10', '>15')
0 голосов
/ 14 января 2019

Я бы использовал apply с stringr::str_detect для этого:

lc_notes <- c("collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph.",
              "collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph.",
              "collected 1.667 man-hr total. mostly cloudy, windy with gusts of 20 mph.")
mph_words<-c(">10", "> 10", ">20", "> 20")

sapply(lc_notes, function(x) any(str_detect(x, mph_words)))

collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph. 
                                                                    TRUE 
collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph. 
                                                                    TRUE 
collected 1.667 man-hr total. mostly cloudy, windy with gusts of 20 mph. 
                                                                   FALSE 

sapply будет проходить через каждый элемент вектора lc_notes, применяя тест к каждому. Затем, используя any, мы упрощаем вектор до единого логического значения.

Если вам нужны номера строк, а не логический вектор, используйте функцию which:

unname(which(sapply(lc_notes, function(x) any(str_detect(x, mph_words)))))
[1] 1 2

Я использовал unname здесь, чтобы подчеркнуть, что вектор, который он возвращает, является индексом элементов в lc_notes, которые соответствуют любому из шаблонов регулярных выражений. Вы также можете сделать обратное и вызвать names, чтобы получить текст строки:

names(which(sapply(lc_notes, function(x) any(str_detect(x, mph_words)))))
[1] "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph." 
[2] "collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph."

Если вы хотите более простое регулярное выражение, которое соответствует пробелам или без пробелов, используйте дополнительный квантификатор ? для пробела:

mph_words<-c("> ?10", "> ?20")
0 голосов
/ 14 января 2019

Отредактировано в соответствии с отредактированным вопросом:
Чтобы найти номера строк, используйте grep

grep("[<>]\\s*\\d+\\b",  lc_notes)

[<>] соответствует <или>
\\s* допускает дополнительные пробелы
\\d соответствует следующим числам.

grep выдаст номера совпадающих строк.

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