Создайте последовательную переменную count на основе значения в другом столбце - PullRequest
1 голос
/ 10 октября 2019

Привет, у меня есть что-то вроде:

df<-data.frame(group=c(1, 1, 1, 1, 2, 2, 2,3,3,3,4,4,4), 
               number=c(0,1,1,1,1,1,0,1,0,1,0,1,1))

Я хочу, чтобы мое 'want' посчитало число 'number' = 1 повторение на 'group'. Затем я хочу максимальное количество повторений (want2). Я хочу, чтобы значение «хочу» сбрасывалось до 1, когда «число» = 0:

dfwant<-data.frame(group=c(1, 1, 1, 1, 2, 2, 2,3,3,3,4,4,4), 
               number=c(0,1,1,1,1,1,0,1,0,1,0,1,1),
               want=c(1,1,2,3,1,2,1,1,1,1,1,1,2),
               want2=c(3,3,3,3,2,2,2,1,1,1,2,2,2))

Спасибо!

Ответы [ 3 ]

3 голосов
/ 10 октября 2019

Поскольку мы хотим выполнить сброс при number = 0, мы group_by group и создаем новую группу всякий раз, когда число равно 0. Затем мы вычисляем want, беря cumsum вхождения 1 в каждой группе иwant2, взяв max в группу.

library(dplyr)

df %>%
  group_by(group, group1 = cumsum(number == 0)) %>%
  mutate(want = cumsum(number == 1), 
         want = replace(want, number == 0, 1)) %>%
  group_by(group) %>%
  mutate(want1 = max(want)) %>%
  select(-group1)

#   group number  want want1
#   <dbl>  <dbl> <dbl> <dbl>
# 1     1      0     1     3
# 2     1      1     1     3
# 3     1      1     2     3
# 4     1      1     3     3
# 5     2      1     1     2
# 6     2      1     2     2
# 7     2      0     1     2
# 8     3      1     1     1
# 9     3      0     1     1
#10     3      1     1     1
#11     4      0     1     2
#12     4      1     1     2
#13     4      1     2     2
2 голосов
/ 10 октября 2019

Мы можем сделать это легко с rleid и rowid из data.table

library(dplyr)
library(data.table)
df %>%
   group_by(group) %>%
   mutate(want = rowid(rleid(number)), want1 = max(want))
# A tibble: 13 x 4
# Groups:   group [4]
#   group number  want want1
#   <dbl>  <dbl> <int> <int>
# 1     1      0     1     3
# 2     1      1     1     3
# 3     1      1     2     3
# 4     1      1     3     3
# 5     2      1     1     2
# 6     2      1     2     2
# 7     2      0     1     2
# 8     3      1     1     1
# 9     3      0     1     1
#10     3      1     1     1
#11     4      0     1     2
#12     4      1     1     2
#13     4      1     2     2

или используя синтаксис data.table

library(data.table)
setDT(df)[, want := rowid(rleid(number)),.(group)][, want1 := max(want), group][]
1 голос
/ 10 октября 2019

В базе вы можете использовать ave для получения cumsum для каждой группы, например:

df$want  <- pmax(1, ave(df$number, df$group, cumsum(df$number==0), FUN=cumsum))
df$want2 <- ave(df$want, df$group, FUN=max)
identical(df, dfwant)
#[1] TRUE

Для сброса, когда df$number==0, вы можете использовать cumsum(df$number==0) в качестведополнительная группировка, как уже показывалось @ Ronak-Shah, для ave.

В случае, если df$number содержит и другие значения, кроме 0 и 1, необходимо использовать:

df$want  <- pmax(1, ave(df$number==1, df$group, cumsum(df$number==0)
    , FUN=cumsum))

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