Расчет разницы во времени для столбца на основе другого столбца - PullRequest
0 голосов
/ 14 марта 2019

У меня есть некоторые данные, которые выглядят так:

> df
                  time region place action
1  2019-01-14 16:00:08      A     G  START
2  2019-01-14 16:00:08      A     I   STOP
3  2019-01-14 16:00:16      A     H  START
4  2019-01-14 16:00:16      A     G   STOP
5  2019-01-14 16:01:40      A     H   STOP
6  2019-01-14 16:01:40      A     G  START
7  2019-01-14 16:01:54      A     G   STOP
8  2019-01-14 16:02:21      A     D  START
9  2019-01-14 16:02:31      A     C  START
10 2019-01-14 16:02:54      A     D   STOP
11 2019-01-14 16:03:12      A     C   STOP
12 2019-01-14 16:03:13      A     E  START
13 2019-01-14 16:03:34      A     E   STOP
14 2019-01-14 16:03:34      A     A  START
15 2019-01-14 16:04:12      A     A   STOP
16 2019-01-14 16:04:12      A     E  START
17 2019-01-14 16:04:17      A     E   STOP
18 2019-01-14 16:04:55      A     F  START
19 2019-01-14 16:05:08      A     B  START
20 2019-01-14 16:05:08      A     F   STOP

Я хочу разницу между START и STOP между местами в каждом регионе.(например, разница между временем в строке 1 и временем в строке 4, потому что это ближайшая остановка для этого места).Вот что у меня так далеко: в конструкции ifelse я пытаюсь найти следующую строку со STOP в столбце действия.

df %>% group_by(region, place) %>%
  mutate(difference = ifelse(action == "STOP", NA, time[which(action == "STOP")[which.max(which(action == "STOP") > row_number())]] - time))

# A tibble: 20 x 5
# Groups:   region, place [9]
   time                region place action difference
   <dttm>              <fct>  <fct> <chr>       <dbl>
 1 2019-01-14 16:00:08 A      g     START        8.52
 2 2019-01-14 16:00:08 A      i     STOP        NA   
 3 2019-01-14 16:00:16 A      h     START       84.2 
 4 2019-01-14 16:00:16 A      g     STOP        NA   
 5 2019-01-14 16:01:40 A      h     STOP        NA   
 6 2019-01-14 16:01:40 A      g     START      -84.2 
 7 2019-01-14 16:01:54 A      g     STOP        NA   
 8 2019-01-14 16:02:21 A      d     START       32.9 
 9 2019-01-14 16:02:31 A      c     START       40.8 
10 2019-01-14 16:02:54 A      d     STOP        NA   
11 2019-01-14 16:03:12 A      c     STOP        NA   
12 2019-01-14 16:03:13 A      e     START       21.3 
13 2019-01-14 16:03:34 A      e     STOP        NA   
14 2019-01-14 16:03:34 A      a     START       38.0 
15 2019-01-14 16:04:12 A      a     STOP        NA   
16 2019-01-14 16:04:12 A      e     START      -38.5 
17 2019-01-14 16:04:17 A      e     STOP        NA   
18 2019-01-14 16:04:55 A      f     START       13.4 
19 2019-01-14 16:05:08 A      b     START       NA   
20 2019-01-14 16:05:08 A      f     STOP        NA  

Разница во времени верназа исключением двух отрицательных (они должны быть ~ 14 и ~ 5).У кого-нибудь есть идея, почему это происходит?Спасибо!

Данные:

df <- structure(
  list(
    time = structure(
      c(
        1547478008.024,
        1547478008.225,
        1547478016.168,
        1547478016.542,
        1547478100.374,
        1547478100.758,
        1547478114.589,
        1547478141.86,
        1547478151.972,
        1547478174.757,
        1547478192.723,
        1547478193.077,
        1547478214.37,
        1547478214.562,
        1547478252.523,
        1547478252.907,
        1547478257.458,
        1547478295.109,
        1547478308.358,
        1547478308.547
      ),
      class = c("POSIXct", "POSIXt"),
      tzone = ""
    ),
    region = structure(
      c(
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L
      ),
      .Label = "A",
      class = "factor"
    ),
    place = structure(
      c(
        7L,
        9L,
        8L,
        7L,
        8L,
        7L,
        7L,
        4L,
        3L,
        4L,
        3L,
        5L,
        5L,
        1L,
        1L,
        5L,
        5L,
        6L,
        2L,
        6L
      ),
      .Label = c("a",
                 "b", "c", "d", "e", "f", "g", "h", "i"),
      class = "factor"
    ),
    action = c(
      "START",
      "STOP",
      "START",
      "STOP",
      "STOP",
      "START",
      "STOP",
      "START",
      "START",
      "STOP",
      "STOP",
      "START",
      "STOP",
      "START",
      "STOP",
      "START",
      "STOP",
      "START",
      "START",
      "STOP"
    )
  ),
  row.names = c(NA, 20L),
  class = "data.frame"
)

1 Ответ

2 голосов
/ 14 марта 2019

Предполагая, что всегда есть ровно один STOP после каждого START и перед следующим START, это будет работать:

df %>% group_by(region, place) %>% 
  arrange(time) %>% 
  mutate(difference=ifelse(action=="STOP", NA, difftime(lead(time),time,units="secs")))

# A tibble: 20 x 5
# Groups:   region, place [9]
   time                region place action difference
   <dttm>              <fct>  <fct> <chr>       <dbl>
 1 2019-01-14 10:00:08 A      g     START        8.52
 2 2019-01-14 10:00:08 A      i     STOP        NA   
 3 2019-01-14 10:00:16 A      h     START       84.2 
 4 2019-01-14 10:00:16 A      g     STOP        NA   
 5 2019-01-14 10:01:40 A      h     STOP        NA   
 6 2019-01-14 10:01:40 A      g     START       13.8 
 7 2019-01-14 10:01:54 A      g     STOP        NA   
 8 2019-01-14 10:02:21 A      d     START       32.9 
 9 2019-01-14 10:02:31 A      c     START       40.8 
10 2019-01-14 10:02:54 A      d     STOP        NA   
11 2019-01-14 10:03:12 A      c     STOP        NA   
12 2019-01-14 10:03:13 A      e     START       21.3 
13 2019-01-14 10:03:34 A      e     STOP        NA   
14 2019-01-14 10:03:34 A      a     START       38.0 
15 2019-01-14 10:04:12 A      a     STOP        NA   
16 2019-01-14 10:04:12 A      e     START        4.55
17 2019-01-14 10:04:17 A      e     STOP        NA   
18 2019-01-14 10:04:55 A      f     START       13.4 
19 2019-01-14 10:05:08 A      b     START       NA   
20 2019-01-14 10:05:08 A      f     STOP        NA 

Примечание. Если вы уверены на 100%, что это предположение верно, вы можете использоватьследующий, который добавляет еще один ifelse, чтобы следующая строка после START была STOP, в противном случае даётся NA:

df %>% group_by(region, place) %>% 
  arrange(time) %>% 
  mutate(difference=ifelse(action=="STOP", NA,
    ifelse(lead(action)=="STOP",difftime(lead(time),time,units="secs"),NA)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...