Уберите часть времени из данных и рассчитайте разницу во времени между последовательными строками, используя R - PullRequest
1 голос
/ 01 октября 2019

У меня есть файл Excel, в котором есть столбец «Время», который представляет время. Тип данных этого столбца - POSIXct. Когда я загружаю файл Excel в R, некоторая случайная часть даты добавляется ко времени, и поэтому я хочу удалить эту случайную дату, добавить только временную часть и затем вычислить разницу между последовательными строками на основе группировки столбцов Emp_Id и Date, гдеМне нужно посмотреть, сколько различий во времени входа и выхода часов каждый день для каждого сотрудника.

Так выглядят мои данные при загрузке в R с добавлением случайной даты.

| Emp_Id |    Date   |                 Time | Time_Event |
|--------|:---------:|---------------------:|------------|
| 95     | 3/14/2019 | 1899-12-31 10:47:12  | Clock-In   |
| 95     | 3/12/2019 | 1899-12-31 10:51:12  | Clock-In   |
| 95     | 3/11/2019 | 1899-12-31 8:15:16   | Clock-Out  |
| 95     | 3/12/2019 | 1899-12-31 8:10:07   | Clock-Out  |
| 95     | 3/11/2019 | 1899-12-31 10:41:51  | Clock-In   |
| 19     | 3/14/2019 | 1899-12-31 6:02:23   | Clock-Out  |
| 19     | 3/18/2019 | 1899-12-31 5:44:23   | Clock-In   |
| 19     | 3/12/2019 | 1899-12-31 6:05:15   | Clock-Out  |
| 19     | 3/12/2019 | 1899-12-31 5:45:57   | Clock-In   |
| 19     | 3/14/2019 | 1899-12-31 5:29:32   | Clock-In   |

Для простоты, данные будут:

Emp_Id <- as.numeric(c("95", "95", "95", "95", "95", "19", "19", "19", "19", "19"))
Date <- c("3/14/2019","3/12/2019","3/11/2019", "3/12/2019","3/11/2019","3/14/2019","3/18/2019","3/12/2019","3/12/2019","3/14/2019")
Time <- as.POSIXct(c("1899-12-31 10:47:12", "1899-12-31 10:51:12", "1899-12-31 8:15:16","1899-12-31 8:10:07", "1899-12-31 10:41:51",
"1899-12-31 6:02:23", "1899-12-31 5:44:23", "1899-12-31 6:05:15", "1899-12-31 5:45:57","1899-12-31 5:29:32"))
Time_Event <- c("Clock-In","Clock-In","Clock-Out","Clock-Out","Clock-In","Clock-Out","Clock-In","Clock-Out","Clock-In","Clock-In")
df2 <- data.frame(Emp_Id,Date,Time,Time_Event, stringsAsFactors = F)
df2$Date= as.Date(df2$Date, format = "%m/%d/%Y")

Использование df$Time <- format(strptime(df$Time, "%Y-%m-%d %H:%M:%S"), "%H:%M:%S") удаляет часть времени, но преобразует тип данных в символ. Поскольку мне нужно вычислить разницу, я не могу сделать это для типа данных символа. Я прошел по этой ссылке Как рассчитать разницу во времени в последовательных строках , но это не помогает.

Я пробовал приведенный ниже код, но получаю сообщение об ошибке из-за типа символьных данных

df2 <- df2 %>%
  arrange(df2$Emp_Id, df2$Date, df2$Time) %>% 
  group_by(df2$Emp_Id,df2$Date) %>%
  mutate(diff = format(strptime(df2$Time, "%Y-%m-%d %H:%M:%S"),"%H:%M:%S")- 
           lag(format(strptime(df2$Time, "%Y-%m-%d %H:%M:%S"),"%H:%M:%S"),
               default = format(strptime(df2$Time, "%Y-%m-%d %H:%M:%S"),"%H:%M:%S")[1]),
         diff_secs = as.numeric(diff, units = 'secs'))

Как получить конечный вывод, похожий на:

| Emp_Id |    Date   |     Time | Time_Event | Diff(In seconds) |
|--------|:---------:|---------:|------------|------------------|
| 19     | 3/12/2019 |  5:45:57 | Clock-In   | NA               |
| 19     | 3/12/2019 | 18:05:15 | Clock-Out  | 44358            |
| 19     | 3/14/2019 |  5:29:32 | Clock-In   | NA               |
| 19     | 3/14/2019 | 18:02:23 | Clock-Out  | 45171            |
| 19     | 3/18/2019 | 17:44:23 | Clock-In   | NA               |
| 95     | 3/11/2019 | 10:41:51 | Clock-In   | NA               |
| 95     | 3/11/2019 | 20:15:16 | Clock-Out  | 33844            |
| 95     | 3/12/2019 | 10:51:12 | Clock-In   | NA               |
| 95     | 3/12/2019 | 20:10:07 | Clock-Out  | 33535            |
| 95     | 3/14/2019 | 10:47:12 | Clock-In   | NA               |

Ответы [ 2 ]

4 голосов
/ 01 октября 2019
library(dplyr)
library(tidyr)
df2 %>%
    arrange(Emp_Id, Date, Time) %>%
    group_by(Emp_Id, Date) %>%
    mutate(Diff = as.numeric(Time - lag(Time), units = "secs")) %>%
    ungroup()
1 голос
/ 01 октября 2019

Мы можем использовать

library(data.table)
setDT(df1)[order(Emp_Id, Date, Time), Date :=
             as.numeric(Time - shift(Time)), .(Emp_Id, Date)]
...