Счетчик максимальной частоты непоследовательных чисел

#r

#r

Вопрос:

У меня есть некоторые данные, в которых одной из переменных является бухгалтер с некоторыми требованиями. Теперь мне нужно знать, сколько раз этот счетчик достигает 1 для каждого идентификатора, если в строке несколько единиц, вам нужно только посчитать 1.

Например, предположим, что идентификатор имеет счетчик: 1, 0, 0, 1, 1, 0, 0, 1,1,1,0,0. Я бы сказал, что идентификатор имеет 3 частоты.

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

Мои данные:

     id <- c(10,10,10,10,10,11,11,11,11,11,11,12,12,12,13, 13, 15, 14)
    counter <- c(0,0,1,1,0,1,0,1,0,1,1,1,1,1,0,0,1,1)
    DF <- data.frame(id, counter); DF
  

Идентификатор 10 имеет 0,0,1,1,0.

5 данных, но только 1 непоследовательный, поэтому для него установлено значение fre_counter 0,0,0,1,0

Мой желаемый результат:

 id <- c(10,10,10,10,10,11,11,11,11,11,11,12,12,12,13, 13, 15, 14)
counter <- c(0,0,1,1,0,1,0,1,0,1,1,1,1,1,0,0,1,1)
frec_counter <- c(0,0,0,1,0,1,0,2,0,0,3,0,0,1,0,0,1,1)
max_counter <- c(1,1,1,1,1,3,3,3,3,3,3,1,1,1,0,0,1,1)
DF <- data.frame(id, counter, frec_counter, max_counter); DF
  

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

1. как frec_counter вычисляется?

2. подсчитайте количество непоследовательных раз, когда появляется 1.. Если есть последовательные 1, последний из них нумеруется. идентификатор 10 содержит 0,0,1,1,0. 5 данных, но только 1 непоследовательный, поэтому для него установлено значение fre_counter 0,0,0,1,0

Ответ №1:

Вот один из подходов с использованием tidyverse:

 library(tidyverse)
DF %>%
  group_by(id) %>% #group by id
  mutate(one = ifelse(counter == lead(counter), 0, counter) #if the leading value is the same replace the value with 0
         one = ifelse(is.na(one), counter, one), #to handle last in group where lead results in NA
         frec_counter1 = cumsum(one), #get cumulative sum of 1s
         frec_counter1 = ifelse(one == 0, 0 , frec_counter1), #replace the cumsum values with 0 where approprate
         max_counter1 = max(frec_counter1)) %>% #get the max frec_counter1 per group
select(-one) #remove dummy variable
#output
      id counter frec_counter max_counter frec_counter1 max_counter1
   <dbl>   <dbl>        <dbl>       <dbl>         <dbl>        <dbl>
 1    10       0            0           1             0            1
 2    10       0            0           1             0            1
 3    10       1            0           1             0            1
 4    10       1            1           1             1            1
 5    10       0            0           1             0            1
 6    11       1            1           3             1            3
 7    11       0            0           3             0            3
 8    11       1            2           3             2            3
 9    11       0            0           3             0            3
10    11       1            0           3             0            3
11    11       1            3           3             3            3
12    12       1            0           1             0            1
13    12       1            0           1             0            1
14    12       1            1           1             1            1
15    13       0            0           0             0            0
16    13       0            0           0             0            0
17    15       1            1           1             1            1
18    14       1            1           1             1            1
  

Ответ №2:

Ваши данные:

 id <- c(10,10,10,10,10,11,11,11,11,11,11,12,12,12,13, 13, 15, 14)
counter <- c(0,0,1,1,0,1,0,1,0,1,1,1,1,1,0,0,1,1)
DF <- data.frame(id, counter)

   id counter
1  10       0
2  10       0
3  10       1
4  10       1
5  10       0
6  11       1
7  11       0
8  11       1
9  11       0
10 11       1
11 11       1
12 12       1
13 12       1
14 12       1
15 13       0
16 13       0
17 15       1
18 14       1
  

Если все, что вам нужно, это итоговые подсчеты, мы могли бы сделать это в базе R:

 counts <- with(DF, split(counter, id))
lengths <- lapply(counts, rle)
final <- lapply(lengths, function(x) sum(x$values == 1))

$`10`
[1] 1

$`11`
[1] 3

$`12`
[1] 1

$`13`
[1] 0

$`14`
[1] 1

$`15`
[1] 1
  

Но поскольку вам конкретно нужен фрейм данных с промежуточными «флагами», набор пакетов tidyverse работает лучше:

 library(tidyverse)

df.new <- DF %>% 
  group_by(id) %>% 
  mutate(
    frec_counter = counter == 1 amp; (is.na(lead(counter)) | lead(counter == 0)),
    frec_counter = as.numeric(frec_counter),
    max_counter = sum(frec_counter)
  )

# A tibble: 18 x 4
# Groups:   id [6]
      id counter frec_counter max_counter
   <dbl>   <dbl>        <dbl>       <dbl>
 1    10       0            0           1
 2    10       0            0           1
 3    10       1            0           1
 4    10       1            1           1
 5    10       0            0           1
 6    11       1            1           3
 7    11       0            0           3
 8    11       1            1           3
 9    11       0            0           3
10    11       1            0           3
11    11       1            1           3
12    12       1            0           1
13    12       1            0           1
14    12       1            1           1
15    13       0            0           0
16    13       0            0           0
17    15       1            1           1
18    14       1            1           1
  

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

1. ваш результат и желаемый результат не совпадают: frec_counter столбцы отличаются

2. Спасибо! он работает идеально!! Импортируемой переменной является max_counter