Masalah: Saya memiliki data deret waktu yang ingin saya subset berdasarkan waktu mulai dan berakhir yang berbeda untuk setiap baris. Setiap titik waktu memiliki nilai per baris (mis. di kolom "nilai_1" hingga "nilai_5").

df <- data.frame(ID = c(101, 102, 103, 104, 105),
                 start = c(1, 2, 1, 3, 2),
                 end = c(2, 4, 3, 4, 3),
                 value_1 = c(8, 10, 4, 7, 6),
                 value_2 = c(3, 6, 9, 2, 5),
                 value_3 = c(4, 4, 10, 1, 6),
                 value_4 = c(5, 7, 8, 9, 2),
                 value_5 = c(4, 6, 3, 8, 10))
df

#    ID start end value_1 value_2 value_3 value_4 value_5
# 1 101     1   2       8       3       4       5       4
# 2 102     2   4      10       6       4       7       6
# 3 103     1   3       4       9      10       8       3
# 4 104     3   4       7       2       1       9       8
# 5 105     2   3       6       5       6       2      10

Sasaran: Saya ingin membuat kerangka data yang hanya mengembalikan nilai untuk kolom antara waktu mulai dan waktu berakhir (inklusif) untuk setiap baris, dan mengembalikan NA untuk nilai baris apa pun di luar waktu mulai dan berakhir, Dengan demikian:

#    ID start end value_1 value_2 value_3 value_4 value_5
# 1 101     1   2       8       3      NA      NA      NA
# 2 102     2   4      NA       6       4       7      NA
# 3 103     1   3       4       9      10      NA      NA
# 4 104     3   4      NA      NA       1       9      NA
# 5 105     2   3      NA       5       6      NA      NA

Sejujurnya saya tidak yakin rute apa yang harus diambil dalam mencoba menyelesaikan masalah ini, jadi saya menantikan ide apa pun. Ini adalah pertama kalinya saya mengajukan pertanyaan di sini, jadi jika Anda memerlukan info lebih lanjut atau jika ada sesuatu yang membingungkan, beri tahu saya. Terima kasih!

r
1
Candle 4 Mei 2020, 22:43

1 menjawab

Jawaban Terbaik

Kita dapat membentuk kembali ke format 'panjang' dan kemudian mengubahnya kembali setelah transformasi

library(dplyr)
library(tidyr)
df %>%
   pivot_longer(starts_with('value')) %>%
   group_by(ID) %>%
   mutate(value = replace(value,
           !row_number() %in% first(start):first(end), NA)) %>% 
   ungroup %>%
   pivot_wider(names_from = name, values_from = value)
# A tibble: 5 x 8
#     ID start   end value_1 value_2 value_3 value_4 value_5
#  <dbl> <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
#1   101     1     2       8       3      NA      NA      NA
#2   102     2     4      NA       6       4       7      NA
#3   103     1     3       4       9      10      NA      NA
#4   104     3     4      NA      NA       1       9      NA
#5   105     2     3      NA       5       6      NA      NA

Atau di base R dengan apply

df[-1] <-  t(apply(df[-1], 1, function(x) {
     x[-(1:2)] <- replace(x[-(1:2)], !seq_along(x[-(1:2)]) %in% x[1]:x[2], NA)
     x}))
3
akrun 4 Mei 2020, 19:55