Cara menentukan kelompok yang memenuhi syarat tertentu selama dua periode waktu berturut-turut di R

katakanlah saya memiliki kumpulan data sederhana yang disebut data:

customer_id <- c("1","1","1","2","2","2","2","3","3","3")
account_id <- as.character(c(11,11,11,55,55,55,55,38,38,38))
obs_date <- c(as.Date("2017-01-01","%Y-%m-%d"), as.Date("2017-02-01","%Y-%m-%d"), as.Date("2017-03-01","%Y-%m-%d"),
          as.Date("2017-12-01","%Y-%m-%d"), as.Date("2018-01-01","%Y-%m-%d"), as.Date("2018-02-01","%Y-%m-%d"),
          as.Date("2018-03-01","%Y-%m-%d"), as.Date("2018-04-01","%Y-%m-%d"), as.Date("2018-05-01","%Y-%m-%d"),
          as.Date("2018-06-01","%Y-%m-%d"))
variable <- c(87,90,100,120,130,150,12,13,15,14)
data <- data.table(customer_id,account_id,obs_date,variable)

dan saya ingin menambahkan variabel lain yang disebut indikator, yang sama dengan 1 untuk pasangan id_pelanggan, id_akun yang memiliki variabel ‹= 90 untuk dua atau lebih tanggal pengamatan berturut-turut (tanggal_obs) dan nol sebaliknya. Oleh karena itu, indikatornya akan sama dengan 1 untuk pasangan id_pelanggan pertama dan ketiga, id_akun dan akan menjadi seperti:

indicator <- c(1,1,1,0,0,0,0,1,1,1)
data <- data.table(customer_id,account_id,obs_date,variable, indicator)

Apakah Anda punya ide bagaimana membuat variabel yang disebut indikator ini? Saya perlu mengelompokkan berdasarkan customer_id, account_id dan mengidentifikasi mereka yang memiliki variabel ‹= 90 untuk setidaknya dua periode waktu berturut-turut. Terima kasih banyak.


person doremi    schedule 25.09.2018    source sumber
comment
Bukankah indikatornya akan bernilai 0 untuk record ketiga karena variabelnya 100, yaitu › 90?   -  person sm925    schedule 25.09.2018
comment
@samadhi Itu per pasangan customer_id, account_id (bukan per record/baris) dan dua baris atau lebih sudah cukup untuk menerapkannya.   -  person Frank    schedule 25.09.2018


Jawaban (2)


Anda bisa melakukan...

data[, v := with(rle(variable <= 90), 
  any(lengths >= 2 & values)
), by=.(customer_id, account_id)]

    customer_id account_id   obs_date variable indicator     v
 1:           1         11 2017-01-01       87         1  TRUE
 2:           1         11 2017-02-01       90         1  TRUE
 3:           1         11 2017-03-01      100         1  TRUE
 4:           2         55 2017-12-01      120         0 FALSE
 5:           2         55 2018-01-01      130         0 FALSE
 6:           2         55 2018-02-01      150         0 FALSE
 7:           2         55 2018-03-01       12         0 FALSE
 8:           3         38 2018-04-01       13         1  TRUE
 9:           3         38 2018-05-01       15         1  TRUE
10:           3         38 2018-06-01       14         1  TRUE

Untuk melihat cara kerjanya, lihat baris yang lebih sederhana:

data[, rle(variable <= 90), by=.(customer_id, account_id)]

   customer_id account_id lengths values
1:           1         11       2   TRUE
2:           1         11       1  FALSE
3:           2         55       3  FALSE
4:           2         55       1   TRUE
5:           3         38       3   TRUE
person Frank    schedule 25.09.2018
comment
Terima kasih banyak, kalian di sini luar biasa! Bolehkah saya bertanya bagian mana dari solusi yang memastikan bahwa jika saya punya mis. tiga baris terakhir variabel dengan nilai 13,100,14 bukannya 13,15,14 (yaitu tidak memenuhi kondisi pada dua baris berturut-turut), v akan menjadi FALSE untuk pasangan id_pelanggan, id_akun ini? Saya tahu ini akan menjadi benar FALSE dalam kasus ini, tapi saya tidak tahu kenapa. Saya rasa saya tidak mengerti cara kerja fungsi rle() ini. - person doremi; 25.09.2018
comment
@doremi Np :) Fungsi rle akan memecahnya menjadi beberapa baris berurutan di mana variabel kondisi ‹= 90 terpenuhi, sehingga akan ada tiga proses dengan lengths masing-masing 1 (dengan values TRUE, FALSE, TRUE), jadi lengths >= 2 kondisi akan gagal untuk semuanya. Coba ?rle dan example(rle) - person Frank; 25.09.2018

Anda dapat menggunakan dplyr::lag() (atau data.table::shift()) untuk melihat nilai sebelumnya dari variable di setiap baris, periksa apakah setiap baris dan baris sebelumnya berada di bawah 90, lalu lihat apakah nilai tersebut benar untuk setiap grup.

data[, indicator := max(variable <= 90 & lag(variable) <= 90, na.rm=T), 
     by=.(customer_id, account_id)]

data sekarang:

    customer_id account_id   obs_date variable indicator
 1:           1         11 2017-01-01       87         1
 2:           1         11 2017-02-01       90         1
 3:           1         11 2017-03-01      100         1
 4:           2         55 2017-12-01      120         0
 5:           2         55 2018-01-01      130         0
 6:           2         55 2018-02-01      150         0
 7:           2         55 2018-03-01       12         0
 8:           3         38 2018-04-01       13         1
 9:           3         38 2018-05-01       15         1
10:           3         38 2018-06-01       14         1

Untuk mengilustrasikan apa yang terjadi:

data[, .(obs_date, 
         variable, 
         lag = lag(variable),
         both_below = variable <= 90 & lag(variable) <= 90
       ), by=.(customer_id, account_id)]

Keluaran:

    customer_id account_id   obs_date variable lag both_below
 1:           1         11 2017-01-01       87  NA         NA
 2:           1         11 2017-02-01       90  87       TRUE
 3:           1         11 2017-03-01      100  90      FALSE
 4:           2         55 2017-12-01      120  NA      FALSE
 5:           2         55 2018-01-01      130 120      FALSE
 6:           2         55 2018-02-01      150 130      FALSE
 7:           2         55 2018-03-01       12 150      FALSE
 8:           3         38 2018-04-01       13  NA         NA
 9:           3         38 2018-05-01       15  13       TRUE
10:           3         38 2018-06-01       14  15       TRUE    
person arvi1000    schedule 25.09.2018
comment
Terima kasih telah menggunakan lag, saya mencoba menjawabnya seperti itu setelah ifelse, tetapi lebih mudah tanpanya. - person Anonymous coward; 25.09.2018