Есть ли функция R для поиска индексов строк, которые содержат определенный шаблон? - PullRequest
0 голосов
/ 02 апреля 2019

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

Некоторые примеры последовательностей:

set.seed(12345)
m <- matrix(sample(1:10, 800, replace=T), ncol=8)
m[sample(1:100, 20, replace=T), 8] <- NA #sequences have variable lengths
head(m)

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    4    2    3    1    1    2    4    4
[2,]    5    4    5    3    3    4    1    2
[3,]    4    5    1    4    2    5    3    3
[4,]    5    4    3    4    2    5    4   NA
[5,]    3    3    4    3    3    4    2    1
[6,]    1    5    4    4    1    5    5    4

Одним из решений является использование двух циклов for для проверки каждой строки на предмет возможного шаблона, однако я обнаружил, что время вычисления быстро увеличивается, когда матрицы получаютбольше.Я попробовал приведенный ниже пример кода для шаблона размера 3, где за действием 1 следуют за действием 2 и действием 3:

pattern <- list(1,2,3)
g <- list()

for (i in 1:NROW(m)){
  if (any(m[i,]==pattern[1], na.rm = TRUE) & any(m[i,]==pattern[2], na.rm = TRUE) & any(m[i,]==pattern[3], na.rm = TRUE)){
    for(ii in 1:(NCOL(m)-2)){
     if((m[i,ii]==pattern[1]) & (m[i,ii+1]==pattern[2]) & (m[i,ii+2]==pattern[3])){
       g <- append(g,i)
     } 
    }
  }
}

Этот цикл, кажется, работает, поскольку он предоставляет список с индексамистроки, соответствующие шаблону (строки 28, 32 и 99).Однако этот метод не масштабируется для длинных / коротких паттернов.Кроме того, в этом примере был проверен шаблон «1 -> 2 -> 3», но мне также хотелось бы иметь возможность проверить шаблоны типа «1 -> (2, 4 или 5) -> 3».

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

1 Ответ

0 голосов
/ 02 апреля 2019

Мы можем начать с создания вектора, который сворачивает каждую строку матрицы в одну строку (в данном случае, разделенную пробелом).Тогда мы можем довольно легко grep it.

mm<-apply(m,1,paste,collapse=" ")
grep("1 2 3", mm)
integer(0)
grep("1 [245] 3", mm)
[1] 14 83

Первая строка grep дает ваш простой поиск (с нулевым результатом).Вторая строка grep показывает, как вы можете искать более сложные паттерны - это будет поиск вашего второго примера: 1 -> 2, 4 или 5 -> 3.

Обратите внимание, что grep даст ваминдексы для строк, которые соответствуют вашему шаблону.В качестве альтернативы, grepl даст вам логический вектор такой же длины, что и m, где TRUE указывает на совпадение.

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