Разница во времени в каждых n/двух строках

У меня есть этот набор данных

library(dplyr)

# creating a dataframe
data_frame <- data.frame(id = c(1,1,2,2,3,3),
                         col2 = c("start", "finish", "start", "finish","start", "finish"),
                         col3 =  c(as.POSIXct("2021-05-08 08:32:07"),
                                   as.POSIXct("2021-05-08 08:32:45"),
                                   as.POSIXct("2020-11-28 23:32:09"),
                                   as.POSIXct("2020-11-28 23:32:25"),
                                   as.POSIXct("2021-05-08 08:32:07"),
                                   as.POSIXct("2021-05-08 08:32:12")))

# computing difference from start to finish
df <- data_frame %>%
  arrange(id) %>%
  mutate(timetaken = col3 - lag(col3))

df

Я хочу

  1. Чтобы рассчитать разницу во времени от начала до конца.
  2. Средняя разница во времени

Чтобы рассчитать разницу во времени, я могу рассчитать задержку, как показано выше. Однако я хочу получить результат следующим образом и вычислить среднее время этой переменной.

> df
  id   col2                col3      timetaken
1  1  start 2021-05-08 08:32:07        NA secs
2  1 finish 2021-05-08 08:32:45        38 secs
3  2  start 2020-11-28 23:32:09        NA secs
4  2 finish 2020-11-28 23:32:25        16 secs
5  3  start 2021-05-08 08:32:07        NA secs
6  3 finish 2021-05-08 08:32:12         5 secs

Есть идеи, как этого добиться?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
74
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете вычислить разницу между «началом» и «финишем» для каждой группы следующим образом:

data_frame %>%
  mutate(timetaken = ifelse(col2 == "start", NA, 
                            col3[col2 == "finish"] - col3[col2 == "start"]), 
         .by = id)

#   id   col2                col3 timetaken
# 1  1  start 2021-05-08 08:32:07        NA
# 2  1 finish 2021-05-08 08:32:45        38
# 3  2  start 2020-11-28 23:32:09        NA
# 4  2 finish 2020-11-28 23:32:25        16
# 5  3  start 2021-05-08 08:32:07        NA
# 6  3 finish 2021-05-08 08:32:12         5

Получите среднюю разницу во времени следующим образом:

mean(data_frame$timetaken, na.rm = TRUE)
#[1] 19.66667
Ответ принят как подходящий

Если вы хотите использовать dplyr::lag():

library(dplyr)

df <- data_frame |>
  mutate(timetaken = col3 - lag(col3), .by = id)

df
#   id   col2                col3 timetaken
# 1  1  start 2021-05-08 08:32:07   NA secs
# 2  1 finish 2021-05-08 08:32:45   38 secs
# 3  2  start 2020-11-28 23:32:09   NA secs
# 4  2 finish 2020-11-28 23:32:25   16 secs
# 5  3  start 2021-05-08 08:32:07   NA secs
# 6  3 finish 2021-05-08 08:32:12    5 secs

и подход dplyr() для получения среднего значения (хотя, как и в предыдущем ответе, я считаю, что в этом случае используется очиститель базы R):

summarise(df, mean(timetaken, na.rm = TRUE))
#   mean(timetaken, na.rm = TRUE)
# 1                 19.66667 secs

Если вам нужна только одна строка для каждого идентификатора, вы можете изменить форму:

tidyr::pivot_wider(data_frame, names_from=col2, values_from=col3) |>
   mutate(timetaken=difftime(finish, start)) |>
   print() |>
   summarise(avg=mean(timetaken, na.rm=TRUE))

# A tibble: 3 x 4
     id start               finish              timetaken
  <dbl> <dttm>              <dttm>              <drtn>   
1     1 2021-05-08 08:32:07 2021-05-08 08:32:45 38 secs  
2     2 2020-11-28 23:32:09 2020-11-28 23:32:25 16 secs  
3     3 2021-05-08 08:32:07 2021-05-08 08:32:12  5 secs 

# A tibble: 1 x 1
  avg          
  <drtn>       
1 19.66667 secs

Предполагая, что это всегда начало/окончание каждой строки, тогда мы можем получить разницу для каждой строки и подмножества чередующихся результатов:

diffSec <- diff(data_frame$col3)[ c(TRUE, FALSE) ]
diffSec
# Time differences in secs
# [1] 38 16  5
mean(diffSec)
# Time difference of 19.66667 secs

Мне кажется, что для желаемой операции данные должны быть в широком формате. Если ваши реальные данные организованы так же хорошо, как и игрушечные, нам не нужно учитывать группировку по id, см. ave().

База R

reshape(data_frame, direction = "wide", idvar = "id", timevar = "col2") |>
  setNames(c("id", "start", "finish")) |> # cosmetics
  transform(diff = difftime(finish, start))

предоставление

  id               start              finish    diff
1  1 2021-05-08 08:32:07 2021-05-08 08:32:45 38 secs
3  2 2020-11-28 23:32:09 2020-11-28 23:32:25 16 secs
5  3 2021-05-08 08:32:07 2021-05-08 08:32:12  5 secs

Чем ваш ответ отличается от моего?

Edward 28.08.2024 14:25

@Эдвард Ааа, извини. Не видел. Свел мой ответ только к базе.

Friede 29.08.2024 14:33

Другие вопросы по теме