Создание индикаторных переменных на основе сопоставления с образцом - PullRequest
0 голосов
/ 08 июня 2018

У меня есть текстовая переменная, и я хочу создать индикаторные переменные, идентифицирующие вектор шаблонов в текстовой переменной.Для каждого шаблона должна быть создана новая индикаторная переменная (предпочтительно с именем переменной, идентичным шаблону.

создать пример данных:

#rm(list = ls())
mydata <- read.table(
  header = T, con <- textConnection
  ('
ID text
6 "aaa"
7 "bbb"
10 "ccc"
11 "a bbb"
29 "a bbb"
30 "bbb"
31 "ddd"
'), stringsAsFactors = FALSE, fill = TRUE, strip.white = TRUE)
close(con)

сопоставление одного шаблона

# a single pattern
mydata$a <- as.integer(grepl(pattern = "aaa", x = mydata$text))
mydata$a

Затем создайте вектор шаблонов:

# multiple patterns stored in a vector
vecpat <- c("aaa", "bbb", "ccc", "ddd", "eee")

И теперь мой вопрос заключается в том, как адаптировать приведенный выше код для сопоставления с шаблоном и создания переменных для нескольких шаблонов. Новые переменные показывают, что они добавляются в фрейм данных,с метками "aaa", "bbb", "ccc", "ddd", "eee" и значениями в диапазоне от 0 до 1.

Я попытался сделать это с помощью str_match_all из пакета stringr. Но яЯ не уверен, как обработать полученный объект. Следующая ссылка (https://rpubs.com/iPhuoc/stringr_manipulation) смотрит на это, но не предоставляет больше информации, чем цитата ниже: «Если вы хотите извлечь за пределы первого номера телефона, например,Второй номер телефона в последней строке, вы можете использовать str_match_all (). Но, как и str_split (), он будет возвращать список с одним компонентом для каждой входной строки, и вам нужно будет использовать lapply (), чтобы обработать результат. "

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Это по сути тот же ответ, что и у Эндрю, но я все равно выкладываю его:

lapply(vecpat, function(x){
    mydata[x] <<- as.numeric(grepl(x, mydata$text))
})
ID  text aaa bbb ccc ddd eee
1  6   aaa   1   0   0   0   0
2  7   bbb   0   1   0   0   0
3 10   ccc   0   0   1   0   0
4 11 a bbb   0   1   0   0   0
5 29 a bbb   0   1   0   0   0
6 30   bbb   0   1   0   0   0
7 31   ddd   0   0   0   1   0

Увидев обновление, я попробовал еще несколько.В моей среде это самое быстрое:

library(stringi)
cbind(mydata, sapply(vecpat, function(x) stri_detect_fixed(mydata$text, x) + 0L))
0 голосов
/ 08 июня 2018

Вы можете просто сделать это ...

for(i in vecpat){
  mydata[, i] <- as.integer(grepl(pattern = i, x = mydata$text))
}

mydata
  ID  text aaa bbb ccc ddd eee
1  6   aaa   1   0   0   0   0
2  7   bbb   0   1   0   0   0
3 10   ccc   0   0   1   0   0
4 11 a bbb   0   1   0   0   0
5 29 a bbb   0   1   0   0   0
6 30   bbb   0   1   0   0   0
7 31   ddd   0   0   0   1   0

Для решения без какого-либо явного цикла вы можете использовать outer с stringr::str_detect (который векторизован) ...

library(stringr)
mydata[, vecpat] <- outer(mydata$text, vecpat, str_detect) + 0L
...