Создание набора индикаторов на основе последовательного появления числа в векторе целых чисел

#r

#r

Вопрос:

Допустим, у меня есть вектор целых чисел

 x <- c(10, 1, 1, 4, 10, 10, 7, 7, 7)
  

и я хочу создать два набора индикаторов на основе этого вектора. Первый индикатор , y , должен быть равен до 1 тех пор, пока x == 10 , а затем равен нулю для остальной части вектора. Важно отметить, что он должен игнорировать любые дополнительные 10 , найденные позже в векторе. Например, учитывая x выше, я бы ожидал

 y <- c(1, 0, 0, 0, 0, 0, 0, 0, 0)
  

и если

 x <- c(10, 10, 10, 1, 1, 5, 10, 7, 9)
  

затем

 y <- c(1, 1, 1, 0, 0, 0, 0, 0, 0)
  

Второй индикатор z должен быть равен 1 для первого элемента после завершения последовательности. Учитывая x приведенные выше векторы, я бы ожидал, что результаты будут:

 z <- c(0, 1, 0, 0, 0, 0, 0, 0, 0)
z <- c(0, 0, 0, 1, 0, 0, 0, 0, 0)
  

Использование одного вектора для вычисления другого — это прекрасно. Я не смог найти аккуратный способ решения этой проблемы, учитывая, что число, используемое для вычисления последовательности, может встречаться позже в векторе, поэтому простая проверка на равенство в моем случае не работает.

Комментарии:

1. Каким будет ваш y when x x <- c(1, 10, 10, 1, 4, 10, 10, 7, 7, 7) , т.е. x не начинается с 10?

2. В этом случае он должен вернуться c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) . Похоже, что приведенное ниже решение @akrun также правильно отражает этот крайний случай, даже если это не произойдет в конкретной настройке, в которой я это применяю. Тем не менее, хороший момент.

Ответ №1:

Мы могли бы использовать rle для изменения значений, которые не равны первому набору из 10, на 0, присвоив этим «значениям» значение FALSE

  (inverse.rle(within.list(rle(x == 10), values[seq_along(values) > 1] <- FALSE)))
#[1] 1 0 0 0 0 0 0 0 0
 (inverse.rle(within.list(rle(x == 10), values[seq_along(values) > 1] <- FALSE)))
#[1] 1 1 1 0 0 0 0 0 0
  

для второго случая получите позицию с which помощью и создайте логический вектор с помощью %in%

 library(data.table)
 ( seq_along(x) %in% which(rleid(x == 10) > 1)[1])
#[1] 0 1 0 0 0 0 0 0 0

  ( seq_along(x) %in% which(rleid(x == 10) > 1)[1])
#[1] 0 0 0 1 0 0 0 0 0
  

Комментарии:

1. Не знал rle . Работает очень хорошо для этого случая.