Ключевая проблема
Я могу заполнить новую строку значениями предыдущей строки. Я могу назначить константы переменным в новом ряду. Но я не могу
рассчитать значения на основе предыдущих строк и назначить их в новой строке.
Фон
У меня есть реальные данные из ПЛК, которые я готовлю к преобразованию в журнал событий для использования с bupaR
.
Приведенные ниже данные ограничены и упрощены, но содержат информацию о ресурсе, отметке времени, типе состояния и идентификаторе события.
Уже достигнут
- Я добавил Error_ID, Error_startTS, Error_EndTS и часть жизненного цикла , как было задокументировано в другом SO вопросе
- Ошибка определяется как любая серия событий, которая начинается с state_type == "error", пока не встретится событие, которое
это не что иное, как «Ошибка», «Comlink Down», «Не активен».
- и номер ошибки был назначен для всех строк одной и той же «трассировки ошибок» («Error_ID»)
- назначено время начала ошибки (отметка времени первой строки ошибки) («Error_startTS»)
- время окончания ошибки, отметка времени 1-й строки после ошибки , другими словами
временная метка события, завершающего ошибку, была назначена («Error_endTS»)
- a «Life_cycle_ID» был присвоен строкам ошибки: «Пуск» или «Текущий».
Цель:
Теперь я хочу вставить новую строку
- с Life_cycle_id == "Завершено"
- после последней строки «продолжается» каждой «трассировки ошибок»
Детали
- Решаемо с
fill()
: копия из последней строки
- "Ресурс"
- "Error_ID",
- «Error_startTS»,
- "Error_endTS"
- Решаемо с
add.row()
: назначить константу
- «Lifecycle_ID» должен быть «завершен»
- «State_type» должно быть «Error»
- Проблематично для меня: присваивать значения на основе значений предыдущих строк
- Отметка времени «Datetime_local» должна получить значение «Error_endTS» в группе
- "event_ID" должен быть увеличен на 1
Данные
my_df <- structure(
list(Resource = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L),
.Label = c("L54", "L60", "L66", "L68", "L70", "L76",
"L78", "L95", "L96", "L97", "L98", "L99"),
class = "factor"),
Datetime_local = structure(c(1535952594, 1535952618, 1535952643, 1535952651,
1535952787, 1535952835, 1535952840, 1535952846,
1535952890, 1535952949, 1535952952, 1535952958,
1535953066),
class = c("POSIXct", "POSIXt"), tzone = ""),
State_type = structure(c(6L, 4L, 8L, 4L, 8L, 4L, 12L, 4L, 8L, 4L, 12L, 4L, 12L),
.Label = c("Comlink Down", "Comlink Up", "Counter", "Error",
"Message", "No part in", "No part out", "Not active",
"Part changing", "Part in", "Part out", "Producing",
"Waiting"),
class = "factor"),
event_ID = c("e00000000000072160", "e00000000000072270", "e00000000000072400",
"e00000000000072430", "e00000000000072810", "e00000000000073110",
"e00000000000073150", "e00000000000073170", "e00000000000073300",
"e00000000000073520", "e00000000000073540", "e00000000000073570",
"e00000000000074040"),
Error_ID = c(0, 1, 1, 1, 1, 1, 0, 2, 2, 2, 0, 3, 0),
Error_startTS = structure(c(NA, 1535952618, 1535952618, 1535952618, 1535952618,
1535952618, NA, 1535952846, 1535952846, 1535952846,
NA, 1535952958, NA),
class = c("POSIXct", "POSIXt"), tzone = ""),
Error_endTS = structure(c(NA, 1535952840, 1535952840, 1535952840, 1535952840,
1535952840, NA, 1535952952, 1535952952, 1535952952,
NA, 1535953066, NA),
class = c("POSIXct", "POSIXt"), tzone = ""),
Lifecycle_ID = c(NA, "Start", "Ongoing", "Ongoing", "Ongoing", "Ongoing", NA,
"Start", "Ongoing", "Ongoing", NA, "Start", NA)),
.Names = c("Resource", "Datetime_local", "State_type", "event_ID", "Error_ID",
"Error_startTS", "Error_endTS", "Lifecycle_ID"),
row.names = 160:172, class = "data.frame")
... выглядит так
# Resource Datetime_local State_type event_ID Error_ID Error_startTS Error_endTS Lifecycle_ID
160 L60 2018-09-03 07:29:54 No part in e00000000000072160 0 <NA> <NA> <NA>
161 L60 2018-09-03 07:30:18 Error e00000000000072270 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Start
162 L60 2018-09-03 07:30:43 Not active e00000000000072400 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
163 L60 2018-09-03 07:30:51 Error e00000000000072430 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
164 L60 2018-09-03 07:33:07 Not active e00000000000072810 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
165 L60 2018-09-03 07:33:55 Error e00000000000073110 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
166 L60 2018-09-03 07:34:00 Producing e00000000000073150 0 <NA> <NA> <NA>
167 L60 2018-09-03 07:34:06 Error e00000000000073170 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Start
168 L60 2018-09-03 07:34:50 Not active e00000000000073300 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Ongoing
169 L60 2018-09-03 07:35:49 Error e00000000000073520 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Ongoing
170 L60 2018-09-03 07:35:52 Producing e00000000000073540 0 <NA> <NA> <NA>
171 L60 2018-09-03 07:35:58 Error e00000000000073570 3 2018-09-03 07:35:58 2018-09-03 07:37:46 Start
172 L60 2018-09-03 07:37:46 Producing e00000000000074040 0 <NA> <NA> <NA>
UDF
ErrorNumberAddLastRow <- function(df){
df %>%
mutate_if(is.factor, as.character) %>%
group_by(Error_ID) %>%
do(add_row(.,
Lifecycle_ID = "Complete", State_type = "Error")) %>%
ungroup() %>%
fill("Resource", "event_ID","Error_ID", "Error_startTS", "Error_endTS") %>%
# mutate(event_ID = event_ID+1) %>% # error: non-numeric argument to binary operator.
# mutate(Datetime_local = Error_endTS) %>% # assigns the same TS to the whole group
arrange(event_ID) %>%
filter( !(Error_ID==0 & Lifecycle_ID=="Complete") | is.na(Lifecycle_ID))
}
Позвоните на udf
ErrorNumberAddLastRow(my_df)
Дает этот результат
# A tibble: 16 x 8
Resource Datetime_local State_type event_ID Error_ID Error_startTS Error_endTS Lifecycle_ID
<chr> <dttm> <chr> <chr> <dbl> <dttm> <dttm> <chr>
1 L60 2018-09-03 07:29:54 No part in e00000000000072160 0 NA NA NA
2 L60 2018-09-03 07:30:18 Error e00000000000072270 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Start
3 L60 2018-09-03 07:30:43 Not active e00000000000072400 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
4 L60 2018-09-03 07:30:51 Error e00000000000072430 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
5 L60 2018-09-03 07:33:07 Not active e00000000000072810 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
6 L60 2018-09-03 07:33:55 Error e00000000000073110 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
7 L60 NA Error e00000000000073110 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Complete
8 L60 2018-09-03 07:34:00 Producing e00000000000073150 0 NA NA NA
9 L60 2018-09-03 07:34:06 Error e00000000000073170 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Start
10 L60 2018-09-03 07:34:50 Not active e00000000000073300 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Ongoing
11 L60 2018-09-03 07:35:49 Error e00000000000073520 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Ongoing
12 L60 NA Error e00000000000073520 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Complete
13 L60 2018-09-03 07:35:52 Producing e00000000000073540 0 NA NA NA
14 L60 2018-09-03 07:35:58 Error e00000000000073570 3 2018-09-03 07:35:58 2018-09-03 07:37:46 Start
15 L60 NA Error e00000000000073570 3 2018-09-03 07:35:58 2018-09-03 07:37:46 Complete
16 L60 2018-09-03 07:37:46 Producing e00000000000074040 0 NA NA NA
Желаемый результат
# # A tibble: 16 x 8
# Resource Datetime_local State_type event_ID Error_ID Error_startTS Error_endTS Lifecycle_ID
# <chr> <dttm> <chr> <chr> <dbl> <dttm> <dttm> <chr>
# 1 L60 2018-09-03 07:29:54 No part in e00000000000072160 0 NA NA NA
# 2 L60 2018-09-03 07:30:18 Error e00000000000072270 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Start
# 3 L60 2018-09-03 07:30:43 Not active e00000000000072400 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
# 4 L60 2018-09-03 07:30:51 Error e00000000000072430 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
# 5 L60 2018-09-03 07:33:07 Not active e00000000000072810 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
# 6 L60 2018-09-03 07:33:55 Error e00000000000073110 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Ongoing
# 7 L60 2018-09-03 07:34:00 Error e00000000000073111 1 2018-09-03 07:30:18 2018-09-03 07:34:00 Complete
# 8 L60 2018-09-03 07:34:00 Producing e00000000000073150 0 NA NA NA
# 9 L60 2018-09-03 07:34:06 Error e00000000000073170 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Start
# 10 L60 2018-09-03 07:34:50 Not active e00000000000073300 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Ongoing
# 11 L60 2018-09-03 07:35:49 Error e00000000000073520 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Ongoing
# 12 L60 2018-09-03 07:35:52 Error e00000000000073521 2 2018-09-03 07:34:06 2018-09-03 07:35:52 Complete
# 13 L60 2018-09-03 07:35:52 Producing e00000000000073540 0 NA NA NA
# 14 L60 2018-09-03 07:35:58 Error e00000000000073570 3 2018-09-03 07:35:58 2018-09-03 07:37:46 Start
# 15 L60 2018-09-03 07:37:46 Error e00000000000073571 3 2018-09-03 07:35:58 2018-09-03 07:37:46 Complete
# 16 L60 2018-09-03 07:37:46 Producing e00000000000074040 0 NA NA NA
Подробно
В строке 7, 12 и 15
- увеличить event_ID с 1
- добавить «Error_endTS» группы к метке времени Datetime_local
Когда вы раскомментируете операторы mutate в функции
mutate(event_ID = event_ID+1) %>%
... возникает ошибка
Ошибка в mutate_impl (.data, точки): Ошибка оценки: не числовой
аргумент бинарного оператора.
mutate(Datetime_local = Error_endTS) %>%
... это назначает один и тот же TS всей группе
Спасибо за любую помощь, которую вы можете оказать мне.