R: найти индексы вектора в другом векторе (если он существует) - PullRequest
0 голосов
/ 14 ноября 2018

Я хотел бы знать начальный индекс вектора в другом векторе. Например, для c(1, 1) и c(1, 0, 0, 1, 1, 0, 1) это будет 4.

Что важно, я хочу искать точно того же вектора. Таким образом, для c(1, 1) внутри c(1, 0, 1, 1, 1, 0) это ЛОЖЬ как c(1, 1) != c(1, 1, 1).

Пока я проверяю, содержится ли короткий вектор в длинном, как это:

any(with(rle(longVec), lengths[as.logical(values)]) == length(shortVec)

Но я не знаю, как определить его индекс ...

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Это работает для приведенных ниже примеров.

a <- c(1,1)
b <- c(1,0,1,1,0,0)
c <- c(1,0,1,1,1,0)

f <- function(x, y) {
  len.x <- length(x)
  len.y <- length(y)
  for(i in 1:(len.y - (len.x - 1))) {
    if(identical(y[i:(i + (len.x - 1))], x)){
      if(y[i + len.x] != x[len.x] & y[i - 1] != x[1]) {return(TRUE)}
    }
  }
  return(FALSE)
}
f(a, b)
# TRUE
f(a, c)
# FALSE
0 голосов
/ 14 ноября 2018

Предполагая, что shortVec содержит только единицы, а longVec содержит только нули, а единицы используют rle и rep для создания вектора lens такой же длины, что и longVec, так что каждый элемент в каждом прогонезаменяется длиной этого пробега.Затем умножьте это на longVec, чтобы обнулить элементы, соответствующие 0 в longVec.Теперь верните индексы, соответствующие элементам, равным length(shortVec), и возьмите первый.

lookup <- function(shortVec, longVec) {
  lens <- with(rle(longVec), rep(lengths, lengths))
  which(lens * longVec == length(shortVec))[1]
}

lookup(c(1,1), c(1, 0, 0, 1, 1, 0, 1))
## [1] 4

lookup(c(1,1), c(1, 0, 0, 1, 1, 1, 0, 1))
## [1] NA
0 голосов
/ 14 ноября 2018

Эта функция должна работать:

my_function <- function(x, find) {
  # we create two matrix from rle function
  m = matrix(unlist(rle(x)), nrow=2, byrow = T) 
  n = matrix(unlist(rle(find)), nrow=2, byrow = T)

  # for each column in m we see if its equal to n
  temp_bool = apply(m, 2, function(x) x == n) # this gives a matrix of T/F
  # then we simply sum by columns, if we have at least a 2 it means that we found (1,1) at least once
  temp_bool = apply(temp_bool, 2, sum)

  # updated part
  if (any(temp_bool==2)) {
    return(position = which(temp_bool==2)+1)
  } else {
    return(position = FALSE)
  }

}


my_function(x, find)
#[1] 4

my_function(y, find)
#[1] FALSE

Чтобы было понятнее, я покажу результаты этих двух apply:

apply(m, 2, function(x) x == n)
#       [,1]  [,2] [,3]  [,4]  [,5]
# [1,] FALSE  TRUE TRUE FALSE FALSE
# [2,]  TRUE FALSE TRUE FALSE  TRUE  # TRUE-TRUE on column 3 is what we seek

apply(temp_bool, 2, sum)
#[1] 1 1 2 0 1

Пример данных:

x <- c(1,0,0,1,1,0,1)
y <-  c(1,0,1,1,1,0)
find <- c(1,1) # as pointed this needs to be a pair of the same number
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...