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

Например, у меня есть следующий фрейм данных:

df <- data.frame(x1 = c(10, 100, 200, 300, 87, 90, 45, 80), 
                 x2 = c("start", "a", "b", "c", "start", "k", "l", "o"))

Я хотел бы создать x3, который начинает считать с 1 каждый раз, когда x2 == "start".

Результирующий фрейм данных должен выглядеть следующим образом:

   x1    x2 x3
1  10 start  1
2 100     a  2
3 200     b  3
4 300     c  4
5  87 start  1
6  90     k  2
7  45     l  3
8  80     o  4

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

2
spies006 28 Фев 2017 в 22:58

2 ответа

Лучший ответ

Используя базу R:

df$x3 <- with(df, ave(x1, cumsum(x2 == 'start'), FUN = seq_along))

Дает :

> df
   x1    x2 x3
1  10 start  1
2 100     a  2
3 200     b  3
4 300     c  4
5  87 start  1
6  90     k  2
7  45     l  3
8  80     o  4

Или с пакетами dplyr или data.table:

library(dplyr)
df %>% 
  group_by(grp = cumsum(x2 == 'start')) %>% 
  mutate(x3 = row_number())

library(data.table)
# option 1
setDT(df)[, x3 := rowid(cumsum(x2 == 'start'))][]
# option 2
setDT(df)[, x3 := 1:.N, by = cumsum(x2 == 'start')][]
7
Jaap 29 Дек 2018 в 18:49

Вот еще один базовый метод R:

df$x3 <- sequence(diff(c(which(df$x2 == "start"), nrow(df)+1)))

Который возвращается

df
   x1    x2 x3
1  10 start  1
2 100     a  2
3 200     b  3
4 300     c  4
5  87 start  1
6  90     k  2
7  45     l  3
8  80     o  4

sequence принимает целочисленный вектор и возвращает счет от 1 до каждой записи вектора. Он задает длину каждого отсчета с помощью diff для вычисления разности позиций начала каждой последовательности. Из-за этого мы должны включить значение позиции после последней строки data.frame, nrow(df)+1.

4
lmo 28 Фев 2017 в 20:06