Diberikan vektor

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

Jumlah sakelar dapat dengan mudah dihitung dengan

cumsum(diff(vec) == 1)

Namun mengingat df

group <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2) 
df_test <- data.frame(vec,group)

Dan menggunakan

df_test <- df_test %>%
  group_by(group) %>%
  mutate(n_switches = cumsum(diff(vec) == 1))%>%
  ungroup()

Perhitungan gagal karena n_switches memiliki 2 baris (1 per grup) kurang dari vec.

Bagaimana saya bisa mengatasi masalah ini dan menghasilkan n_switch per grup? Bantuan apa pun akan sangat dihargai!

3
another_newbie 9 Januari 2021, 20:09

2 jawaban

Jawaban Terbaik

Dengan diff, output selalu merupakan output dengan length 1 perbedaan dari panjang output aslinya. Kita dapat menambahkan elemen untuk membuat panjangnya sama dengan mutate ingin mengembalikan kolom dengan length yang sama

library(dplyr)
df_test %>%
 group_by(group) %>%
 mutate(n_switches = cumsum(c(FALSE, diff(vec) == 1))) %>%
 ungroup
3
akrun 9 Januari 2021, 17:12

Berikut adalah opsi lain selain diff, yang menerapkan gregexpr untuk memposisikan shift

df_test %>%
  group_by(group) %>%
  mutate(n_switches = cumsum(replace(0 * vec, gregexpr("(?<=0)1", paste0(vec, collapse = ""), perl = TRUE)[[1]], 1))) %>%
  ungroup()

# A tibble: 20 x 3
     vec group n_switches
   <dbl> <dbl>      <dbl>
 1     1     1          0
 2     0     1          0
 3     1     1          1
 4     1     1          1
 5     1     1          1
 6     0     1          1
 7     0     1          1
 8     1     1          2
 9     1     1          2
10     0     1          2
11     1     2          0
12     0     2          0
13     1     2          1
14     0     2          1
15     1     2          2
16     1     2          2
17     1     2          2
18     0     2          2
19     1     2          3
20     0     2          3

Realisasi serupa tetapi dengan data.table

setDT(df_test)[
  ,
  n_switches := cumsum(replace(0 * vec, gregexpr("(?<=0)1", paste0(vec, collapse = ""), perl = TRUE)[[1]], 1)),
  group
]

> df_test
    vec group n_switches
 1:   1     1          0
 2:   0     1          0
 3:   1     1          1
 4:   1     1          1
 5:   1     1          1
 6:   0     1          1
 7:   0     1          1
 8:   1     1          2
 9:   1     1          2
10:   0     1          2
11:   1     2          0
12:   0     2          0
13:   1     2          1
14:   0     2          1
15:   1     2          2
16:   1     2          2
17:   1     2          2
18:   0     2          2
19:   1     2          3
20:   0     2          3
1
ThomasIsCoding 9 Januari 2021, 20:31