Ulangi baris lalu manipulasi baris tersebut menggunakan tabel data di R

Hai, saya baru mengenal sintaks tabel data di R (dan R secara umum) dan memerlukan bantuan untuk mengulang baris tertentu dan secara bertahap meningkatkannya berdasarkan kategori.

Informasi tabel data tiruan saya ada di bawah:

> head(dt)
       Time Values1 Values2 Values3 Category
1: 00:15:00       1       2     1.5        A
2: 00:30:00       3       4     2.5        A
3: 00:45:00       5       6     3.5        A
4: 01:00:00       7       8     4.5        A
5: 01:15:00       9      10     5.5        A
6: 01:30:00      11      12     6.5        A

> tail(dt)
       Time Values1 Values2 Values3 Category
1: 22:45:00     182     181    92.5        B
2: 23:00:00     184     183    93.5        B
3: 23:15:00     186     185    94.5        B
4: 23:30:00     188     187    95.5        B
5: 23:45:00     190     189    96.5        B
6: 00:00:00     192     191    97.5        B

> str(dt)
Classes ‘data.table’ and 'data.frame':  192 obs. of  5 variables:
 $ Time    :Class 'ITime'  int [1:192] 900 1800 2700 3600 4500 5400 6300 7200 8100 9000 ...
 $ Values1 : int  1 3 5 7 9 11 13 15 17 19 ...
 $ Values2 : int  2 4 6 8 10 12 14 16 18 20 ...
 $ Values3 : num  1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5 10.5 ...
 $ Category: chr  "A" "A" "A" "A" ...
 - attr(*, ".internal.selfref")=<externalptr> 

Jika Kategorinya adalah A, saya ingin mengekstrapolasi setiap nilai (disorot kuning) di kolom Waktu menjadi satu menit sementara kolom lainnya masih memiliki nilai yang sama. Perhatikan bahwa, jika waktunya 00:15, maka bagian ekstrapolasi saya akan memiliki waktu dari 00:01 hingga 00:14 dan 00:16 hingga 00:29, seperti yang ditunjukkan di bawah ini:

---Sasaran---:

masukkan deskripsi gambar di sini

Jika kategori B, maka waktu ekstrapolasinya adalah 5 menit.

Hasil akhirnya akan memiliki data asli dengan semua ekstrapolasi waktu dan tidak ada nilai waktu duplikat berdasarkan Kategori.

--- Proses Berpikir----:

Strategi saya adalah membagi ke dalam kategori A dan B, menemukan cara untuk menambahkan waktu ekstrapolasi dan menambahkannya kembali ke tabel data asli.

Sejauh ini, saya tahu cara membagi ke dalam kategori A dan B, membuat fungsi untuk menambahkan menit ke kolom as.ITime ketik Waktu dan ulangi setiap baris di kolom Waktu

add_minutes <- function(m) {
  x <- m * 60
  return(x)
}

A <- dt[Category == 'A']
B <- dt[Category == 'B']

A <- A[,list(freq=rep(1,14)), by =.(Time,Values1,Values2,Values3,Category)][,freq:=NULL]

Namun, saya tidak tahu cara menggabungkan fungsi add_menit() ke baris berulang tersebut untuk:

  1. Atur ulang waktu untuk setiap nilai waktu asli. Misalnya, jika waktu asli adalah 00:30. Saya berhasil mengulang baris itu sebanyak 14 kali, lalu saya ingin 14 kemunculan 00:30 itu berurutan dari 00:31 hingga 00:44. Jika waktu aslinya 00:45, maka saya ingin urutannya dari 00:46 hingga 00:59, dan seterusnya.

  2. Tambahkan ini kembali ke tabel data asli

Terima kasih sebelumnya atas bantuan Anda!!


person BoBoMann    schedule 14.08.2020    source sumber
comment
Harap berikan kode untuk mereproduksi kumpulan data Anda dt. Saya yakin, bagian yang menarik bukanlah head() atau tail() melainkan bagian tengah tempat Category beralih dari A ke B. Di sinilah jawaban-jawaban yang berbeda perlu dibandingkan. Terima kasih.   -  person Uwe    schedule 21.08.2020


Jawaban (2)


Sayangnya, rolling join seperti yang disarankan oleh pseudospin tidak akan mengembalikan hasil yang diharapkan karena as.ITime("00:00:00") adalah bagian dari rangkaian waktu dt dan dengan demikian akan diteruskan ke langkah waktu tambahan di 00:01:00, 00:02:00, 00:03:00, dst. untuk Category A, atau 00:05:00, 00:10:00 untuk Category B, resp. (Perhatikan bahwa as.ITime("24:00:00") == as.ITime("00:00:00")).

Pendekatan di bawah ini

  1. membuat semua langkah waktu yang diperlukan completed_ts untuk setiap Category
  2. kanan bergabung dengan dt yang menambahkan banyak NA ke kolom nilai
  3. mengisi nilai yang hilang untuk setiap Category pada pengamatan terakhir yang dilakukan,
  4. dan mengisi nilai yang hilang di bagian atas setiap Category dengan pengamatan berikutnya dilakukan mundur, pada akhirnya.
completed_ts <- rbind(
  data.table(Time = as.ITime(seq(1L, 1440L, 1L) * 60L), Category = "A"),
  data.table(Time = as.ITime(seq(5L, 1440L, 5L) * 60L), Category = "B")
)
res <- dt[completed_ts, on = .(Time, Category)]
cols <- paste0("Values", 1:3)
res[, (cols) := lapply(.SD, nafill, type = "locf"), .SDcols = cols, by = Category]
res[, (cols) := lapply(.SD, nafill, type = "nocb"), .SDcols = cols, by = Category]

# print interesting parts of the result
res[Category == "A", .SD[c(1:16, .N - 16:0)]]
res[Category == "B", .SD[c(1:4, .N - 4:0)]]
        Time Values1 Values2 Values3 Category
 1: 00:01:00       1       2     1.5        A
 2: 00:02:00       1       2     1.5        A
 3: 00:03:00       1       2     1.5        A
 4: 00:04:00       1       2     1.5        A
 5: 00:05:00       1       2     1.5        A
 6: 00:06:00       1       2     1.5        A
 7: 00:07:00       1       2     1.5        A
 8: 00:08:00       1       2     1.5        A
 9: 00:09:00       1       2     1.5        A
10: 00:10:00       1       2     1.5        A
11: 00:11:00       1       2     1.5        A
12: 00:12:00       1       2     1.5        A
13: 00:13:00       1       2     1.5        A
14: 00:14:00       1       2     1.5        A
15: 00:15:00       1       2     1.5        A
16: 00:16:00       1       2     1.5        A
17: 23:44:00     187     188    94.5        A
18: 23:45:00     189     190    95.5        A
19: 23:46:00     189     190    95.5        A
20: 23:47:00     189     190    95.5        A
21: 23:48:00     189     190    95.5        A
22: 23:49:00     189     190    95.5        A
23: 23:50:00     189     190    95.5        A
24: 23:51:00     189     190    95.5        A
25: 23:52:00     189     190    95.5        A
26: 23:53:00     189     190    95.5        A
27: 23:54:00     189     190    95.5        A
28: 23:55:00     189     190    95.5        A
29: 23:56:00     189     190    95.5        A
30: 23:57:00     189     190    95.5        A
31: 23:58:00     189     190    95.5        A
32: 23:59:00     189     190    95.5        A
33: 00:00:00     191     192    96.5        A
        Time Values1 Values2 Values3 Category
       Time Values1 Values2 Values3 Category
1: 00:05:00       2       1     2.5        B
2: 00:10:00       2       1     2.5        B
3: 00:15:00       2       1     2.5        B
4: 00:20:00       2       1     2.5        B
5: 23:40:00     188     187    95.5        B
6: 23:45:00     190     189    96.5        B
7: 23:50:00     190     189    96.5        B
8: 23:55:00     190     189    96.5        B
9: 00:00:00     192     191    97.5        B

Perhatikan bahwa fungsi nafill() data.tables saat ini hanya mendukung tipe data double dan integer. Jika perlu mengisi tipe data lain silakan lihat zoo::na.locf().

Data yang dapat direproduksi

library(data.table)
dtA <- data.table(Time = seq(as.ITime("00:15:00"), by = 900L, length.out = 96L),
                  Values1 = seq(1L, by = 2L, length.out = 96L),
                  Values2 = seq(2L, by = 2L, length.out = 96L),
                  Values3 = seq(1.5, by = 1.0, length.out = 96L),
                  Category = rep("A", 96L))
dtB <- data.table(Time = seq(as.ITime("00:15:00"), by = 900L, length.out = 96L),
                  Values1 = seq(to = 192L, by = 2L, length.out = 96L),
                  Values2 = seq(to = 191L, by = 2L, length.out = 96L),
                  Values3 = seq(to = 97.5, by = 1.0, length.out = 96L),
                  Category = rep("B", 96L))

dt <- rbind(dtA, dtB)  
person Uwe    schedule 21.08.2020

Penggulungan ajaib bergabung dalam data.table.

desire <- rbind(
  data.table(Category = "A", Time = as.ITime(seq(1, 1440, 1)*60)),
  data.table(Category = "B", Time = as.ITime(seq(5, 1440, 5)*60))
)
dt[desire, on = c('Category','Time'), roll = TRUE, rollends = c(TRUE, TRUE)]
person pseudospin    schedule 19.08.2020
comment
Jawabannya tidak memberikan hasil yang diharapkan. - person Uwe; 21.08.2020
comment
Suara negatifnya agak kasar karena ini menjadi dasar jawaban hampir satu baris untuk masalah yang tampaknya sulit. Bagaimanapun, bukankah solusi yang lebih baik untuk masalah 00:00:00 hanya dengan mengakui bahwa Anda seharusnya tidak memasukkannya ke dalam data masukan Anda dan kemudian hal di atas berfungsi dengan baik. - person pseudospin; 21.08.2020
comment
Terima kasih telah memperkenalkan saya pada rolling join di data.table, luar biasa! - person BoBoMann; 01.11.2020