如何将时间码转换为转码

how to transform time codes into turn codes

我想像这样转换时间码

library(lubridate)
library(tidyverse)

df_time <- tibble(time = c(ymd_hms("2020_01_01 00:00:01"),
                           ymd_hms("2020_01_01 00:00:02"),
                           ymd_hms("2020_01_01 00:00:03"),
                           ymd_hms("2020_01_01 00:00:04"),
                           ymd_hms("2020_01_01 00:00:05"),
                           ymd_hms("2020_01_01 00:00:06")),
                  a = c(0, 1, 1, 1, 1, 0),
                  b = c(0, 0, 1, 1, 0, 0))

导致

>df_time
# A tibble: 6 x 3
  time                    a     b
  <dttm>              <dbl> <dbl>
1 2020-01-01 00:00:01     0     0
2 2020-01-01 00:00:02     1     0
3 2020-01-01 00:00:03     1     1
4 2020-01-01 00:00:04     1     1
5 2020-01-01 00:00:05     1     0
6 2020-01-01 00:00:06     0     0

转换为代码(a.k.a。事件代码/"start stop data")。应该类似于以下 df:

df_turn <- tibble(start = c(ymd_hms("2020_01_01 00:00:02"),
                            ymd_hms("2020_01_01 00:00:03")),
                  end = c(ymd_hms("2020_01_01 00:00:05"),
                          ymd_hms("2020_01_01 00:00:04")),
                  code = c("a", "b"))


> df_turn
# A tibble: 2 x 3
  start               end                 code 
  <dttm>              <dttm>              <chr>
1 2020-01-01 00:00:02 2020-01-01 00:00:05 a    
2 2020-01-01 00:00:03 2020-01-01 00:00:04 b  


谢谢!

一种方法是将数据帧转换为长数据帧并过滤掉 0。一旦你这样做了,你只需要每组的最大值和最小值(根据 time),所以我们可以在分组后使用 slice 来做到这一点。最后一步是创建一个包含 startend 的列,并将生成的数据框简单地转换为宽格式,即

library(dplyr)
library(tidyr)

df_time %>% 
 pivot_longer(cols = -1, names_to = 'code') %>% 
 filter(value != 0) %>% 
 group_by(code) %>%
 slice(c(which.min(time), which.max(time))) %>% 
 select(-value) %>% 
 mutate(new = c('start', 'end')) %>% 
 pivot_wider(names_from = new, values_from = time)

这给出了,

# A tibble: 2 x 3
# Groups:   name [2]
  code   start               end                
  <chr> <dttm>              <dttm>             
1 a     2020-01-01 00:00:02 2020-01-01 00:00:05
2 b     2020-01-01 00:00:03 2020-01-01 00:00:04