簡體   English   中英

根據另一列的值重新編碼時間變量

[英]Recode time variable based on the value of another column

我有一個time變量,我想根據另一列中事件的變化對其進行重新編碼。 具體來說,如果y中的值從 1 變為 0,則time將從 0 重新開始。我還需要在同一個人內完成此刷新(即按id排序)。 總時間長度可能因人而異。 這是原始數據集:

df <- data.frame(id = rep(1:3, c(5,6,7)), time = c(seq(from = 0, to = 2000, by = 500), seq(from = 0, to = 2500, by = 500), seq(from = 0, to = 3000, by = 500)), y = c(0,0,1,0,0,0,0,1,1,0,1,0,1,1,0,1,1,0))
df
   id time y
1   1    0 0
2   1  500 0
3   1 1000 1
4   1 1500 0
5   1 2000 0
6   2    0 0
7   2  500 0
8   2 1000 1
9   2 1500 1
10  2 2000 0
11  2 2500 1
12  3    0 0
13  3  500 1
14  3 1000 1
15  3 1500 0
16  3 2000 1
17  3 2500 1
18  3 3000 0

最終結果應該是這樣的(注意第 4、10、15 和 18 行的刷新時間。三個人的時間長度也不同):

   id time y
1   1    0 0
2   1  500 0
3   1 1000 1
4   1    0 0
5   1  500 0
6   2    0 0
7   2  500 0
8   2 1000 1
9   2 1500 1
10  2    0 0
11  2  500 1
12  3    0 0
13  3  500 1
14  3 1000 1
15  3    0 0
16  3  500 1
17  3 1000 1
18  3    0 0

如何做到這一點? 謝謝!

dplyr

library(dplyr)
df %>%
  group_by(id) %>%
  mutate(grp = cumsum(y == 0 & lag(y == 1, default = FALSE))) %>%
  group_by(id, grp) %>%
  mutate(time = time - first(time)) %>%
  ungroup()
# # A tibble: 18 x 4
#       id  time     y   grp
#    <int> <dbl> <dbl> <int>
#  1     1     0     0     0
#  2     1   500     0     0
#  3     1  1000     1     0
#  4     1     0     0     1
#  5     1   500     0     1
#  6     2     0     0     0
#  7     2   500     0     0
#  8     2  1000     1     0
#  9     2  1500     1     0
# 10     2     0     0     1
# 11     2   500     1     1
# 12     3     0     0     0
# 13     3   500     1     0
# 14     3  1000     1     0
# 15     3     0     0     1
# 16     3   500     1     1
# 17     3  1000     1     1
# 18     3     0     0     2

底座 R

df$grp <- ave(df$y, df$id, FUN = function(z) cumsum(c(FALSE, z[-1] == 0 & z[-length(z)] == 1)))
df$time <- ave(df$time, df[,c("id", "grp")], FUN = function(z) z - z[1])

data.table

library(data.table)
as.data.table(df)[, grp := cumsum(y == 0 & shift(y == 1, type = "lag", fill = FALSE)), by = id
  ][, time := time - first(time), by = .(id, grp)][]

另一個不涉及time變量的解決方案是:

df %>% group_by(id) %>%
  mutate(count = cumsum(y == 0 & lag(y, default = 0) == 1)) %>% 
  group_by(id, count) %>% 
  mutate(time = 500*(row_number()-1))

      id  time     y count
   <int> <dbl> <dbl> <int>
 1     1     0     0     0
 2     1   500     0     0
 3     1  1000     1     0
 4     1     0     0     1
 5     1   500     0     1
 6     2     0     0     0
 7     2   500     0     0
 8     2  1000     1     0
 9     2  1500     1     0
10     2     0     0     1
11     2   500     1     1
12     3     0     0     0
13     3   500     1     0
14     3  1000     1     0
15     3     0     0     1
16     3   500     1     1
17     3  1000     1     1
18     3     0     0     2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM