R: подсчитывать последовательные вхождения значений в одном столбце

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

Ниже приведен пример ввода и ожидаемого результата.

dataset <- data.frame(input = c("a","b","b","a","a","c","a","a","a","a","b","c")) dataset$counter <- c(1,1,2,1,2,1,1,2,3,4,1,1) dataset # input counter # 1 a 1 # 2 b 1 # 3 b 2 # 4 a 1 # 5 a 2 # 6 c 1 # 7 a 1 # 8 a 2 # 9 a 3 # 10 a 4 # 11 b 1 # 12 c 1 

Мой вопрос очень похож на этот: кумулятивная последовательность появления значений .

2 Solutions collect form web for “R: подсчитывать последовательные вхождения значений в одном столбце”

Вам нужно использовать sequence и rle :

 > sequence(rle(as.character(dataset$input))$lengths) [1] 1 1 2 1 2 1 1 2 3 4 1 1 

Эффективная и более простая версия функции, описанной ниже, доступна теперь в пакете data.table, называемом rleid . Используя это, это просто:

 setDT(dataset)[, counter := seq_len(.N), by=rleid(input)] 

См. « ?rleid для получения дополнительной информации об использовании и примерах. Спасибо @Henrik за предложение обновить этот пост.


rle – это, безусловно, самый удобный способ сделать это (+1 @ Ananda’s). Но можно было бы лучше (с точки зрения скорости) увеличить данные. Вы можете использовать функции duplist и vecseq (не экспортируемые) из data.table следующим образом:

 require(data.table) arun < - function(y) { w = data.table:::duplist(list(y)) w = c(diff(w), length(y)-tail(w,1L)+1L) data.table:::vecseq(rep(1L, length(w)), w, length(y)) } x <- c("a","b","b","a","a","c","a","a","a","a","b","c") arun(x) # [1] 1 1 2 1 2 1 1 2 3 4 1 1 

Бенчмаркинг по большим данным:

 set.seed(1) x < - sample(letters, 1e6, TRUE) # rle solution ananda <- function(y) { sequence(rle(y)$lengths) } require(microbenchmark) microbenchmark(a1 <- arun(x), a2<-ananda(x), times=100) Unit: milliseconds expr min lq median uq max neval a1 <- arun(x) 123.2827 132.6777 163.3844 185.439 563.5825 100 a2 <- ananda(x) 1382.1752 1899.2517 2066.4185 2247.233 3764.0040 100 identical(a1, a2) # [1] TRUE 
  • TwitteR, ROAuth и Windows: зарегистрируйтесь в порядке, но проверка сертификата не выполнена
  • Одновременное принуждение нескольких столбцов к факторам
  • Как отсортировать вектор символа, где элементы содержат буквы и числа в R?
  • Преобразование NA в факторный уровень
  • Пример n случайных строк для каждой группы в кадре данных
  • R: Разбить несбалансированный список в столбце data.frame
  • Есть ли способ изменить расстояние между элементами легенды в ggplot2?
  • Контролировать внешний вид ggplot2, не затрагивая сюжет
  • Используйте значение из предыдущей строки в расчете R.table.table
  • Форматирование реактивных кадров данных в Shiny
  • Как я могу поместить преобразованную шкалу в правую сторону ggplot2?
  • Interesting Posts

    Какой код установки должен идти в Form Constructors по сравнению с событием Form Load?

    Флаги для включения подробных и подробных предупреждений g ++

    Почему у меня одинаковые файлы в одном каталоге, в Windows 7?

    Не может связываться с ‘for’, поскольку это не известное свойство native angular2

    Может ли JSON начать с “[“?

    Мышь двойного щелчка мышью

    Вызов функции для каждого вариационного аргумента шаблона и массива

    Как суммировать диапазон ячеек со значениями N / A?

    Инъекция зависимостей – требуется новый экземпляр для нескольких методов classов

    Проверка на нуль до отправки события … streamобезопасная?

    Установить фокус на EditText

    Обнаружение пикового сигнала в реальном времени

    Права доступа WCF ServiceHost

    Как заставить первый кадр быть ключевым кадром?

    Прерывистые блокировки, неспособные диагностировать более года

    Давайте будем гением компьютера.