У меня есть датафрейм df1
, который суммирует обнаружения различных животных с течением времени. Столбец Rec
указывает, какое устройство его обнаружило (V4
, V6
и т. Д.), А столбец Ind
указывает человека.
Я хочу удалить строки, которые удовлетворяют следующему условию: «есть обнаружение для того же животного в течение предыдущих 55 секунд» (не имеет значения, если обнаружение происходит от другого приемника).
Кроме того, я хочу создать следующие столбцы:
1) Num_Rec
: Суммируется, как ДРУГОЕ Rec
обнаружило животное в указанном интервале 55 с.
2) Which_Rec
: в нем обобщено название ДРУГОГО Rec
, обнаружившего животное в указанном интервале 55 с.
Если в интервале 55 с одно и то же животное дважды поймано одним и тем же Rec
(т. Е. Строки 12 и 13 в df1
), я считаю 2-й ряд (= обнаружение) ошибкой (не возможно, что один и тот же приемник дважды ловит одного и того же животного за 55 с), и я не принимаю во внимание этот ряд в столбцах Num_Rec
и Which_Rec
(т. е. в Result
я не считаю df1$Datetime[13]
ни в Result$Num_Rec[11]
, ни в Result$Which_Rec[11]
).
Как пример:
df1<-data.frame(DateTime=c("2016-08-01 12:04:07","2016-08-01 12:06:07","2016-08-01 12:06:58","2016-08-01 13:12:12","2016-08-01 14:04:07","2016-08-01 13:12:45","2016-08-01 15:04:07","2016-08-01 17:13:16","2016-08-01 17:21:16","2016-08-01 17:21:34","2016-08-01 17:23:42","2016-08-01 17:27:16","2016-08-01 17:27:22","2016-08-01 17:28:01","2016-08-01 17:29:28","2016-08-01 17:28:08"),Rec=c("V6", "V7", "V6", "V6", "V7", "V7", "V6", "V7", "V7","V7","V6","V6", "V6", "V9", "V7", "V4"),Ind=c(16, 17, 16, 16, 17, 16, 17, 16, 17, 16, 16, 17, 17, 17, 16, 17))
df1$DateTime<- as.POSIXct(df1$DateTime, format= "%Y-%m-%d %H:%M:%S", tz= "UTC")
df1
DateTime Rec Ind
1 2016-08-01 12:04:07 V6 16
2 2016-08-01 12:06:07 V7 17
3 2016-08-01 12:06:58 V6 16
4 2016-08-01 13:12:12 V6 16
5 2016-08-01 14:04:07 V7 17
6 2016-08-01 13:12:45 V7 16
7 2016-08-01 15:04:07 V6 17
8 2016-08-01 17:13:16 V7 16
9 2016-08-01 17:21:16 V7 17
10 2016-08-01 17:21:34 V7 16
11 2016-08-01 17:23:42 V6 16
12 2016-08-01 17:27:16 V6 17
13 2016-08-01 17:27:22 V6 17
14 2016-08-01 17:28:01 V9 17
15 2016-08-01 17:29:28 V7 16
16 2016-08-01 17:28:08 V4 17
То, что я хочу получить, это:
Result
DateTime Rec Ind Num_Rec Which_Rec
1 2016-08-01 12:04:07 V6 16 0 NA
2 2016-08-01 12:06:07 V7 17 0 NA
3 2016-08-01 12:06:58 V6 16 0 NA
4 2016-08-01 13:12:12 V6 16 1 V7
5 2016-08-01 14:04:07 V7 17 0 NA
6 2016-08-01 15:04:07 V6 17 0 NA
7 2016-08-01 17:13:16 V7 16 0 NA
8 2016-08-01 17:21:16 V7 17 0 NA
9 2016-08-01 17:21:34 V7 16 0 NA
10 2016-08-01 17:23:42 V6 16 0 NA
11 2016-08-01 17:27:16 V6 17 2 V9 V4
12 2016-08-01 17:29:28 V7 16 0 NA
Note1: In `Result[4,]` there is a detection of the individual `16` at 13:12:12 and in an interval of 55s there is another detection (indicated in `Num_Rec`) in the `Rec` number `V7` (indicated in `Which_Rec`).
Note2: In `Result[11,]` there is one detection of the individual `17` at 17:27:16 in `Rec` `V6`, and after that, in an interval of 55s, there are two more TRUE detections, as it is indicated in `Num_Rec` with a `2`. In `Which_Rec` we specify the name of the receivers. In this case:`V9` and `V4`. We have also a FALSE detection in this interval of 55s that starts at 17:27:16. It is in row 13 in `df1` (It is a false detection because an animal can't be detected twice for the same `Rec` in 55s).
Я хотел бы знать, как это сделать с большим кадром данных. Я думаю, это возможно с пакетом dplyr
, но я не знаю, как.
Я попробовал это, как предложил коллега из StackOverflow в ответах:
library(tidyverse)
df <- data.frame(DateTime=c("2016-08-01 12:04:07","2016-08-01 12:06:07","2016-08-01 12:06:58","2016-08-01 13:12:12","2016-08-01 14:04:07","2016-08-01 13:12:45","2016-08-01 15:04:07","2016-08-01 17:13:16","2016-08-01 17:21:16","2016-08-01 17:21:34","2016-08-01 17:23:42","2016-08-01 17:27:16","2016-08-01 17:27:22","2016-08-01 17:28:01","2016-08-01 17:29:28","2016-08-01 17:28:08"),Rec=c("V6", "V7", "V6", "V6", "V7", "V7", "V6", "V7", "V7","V7","V6","V6", "V6", "V9", "V7", "V4"),Ind=c(16, 17, 16, 16, 17, 16, 17, 16, 17, 16, 16, 17, 17, 17, 16, 17))%>%
mutate(Rec = as.character(Rec),
DateTime = as.POSIXct(as.character(DateTime))) %>%
as_tibble()
First I define a delete_flag by checking if the same individual has been caught more than once within 55 seconds. Then I filter the data accordingly.
Next I use `pmap` to get `Num_Rec` and `Which_Rec`:
df %>%
mutate(delete_flag = map2_lgl(DateTime, Ind, ~filter(df, DateTime < .x, DateTime >= .x - 55,
Ind == .y) %>% nrow %>% as.logical())) %>%
filter(!delete_flag) %>%
select(-delete_flag) %>%
mutate(x = pmap(list(DateTime, Rec, Ind), ~filter(df, DateTime > ..1, DateTime <= ..1 +55,
Rec != ..2, Ind == ..3) %>%
summarise(Num_Rec = n(),
Which_Rec = paste0(Rec, collapse = " ")))) %>%
unnest()
DateTime Rec Ind Num_Rec Which_Rec
<dttm> <chr> <dbl> <int> <chr>
1 2016-08-01 12:04:07 V6 16 0 ""
2 2016-08-01 12:06:07 V7 17 0 ""
3 2016-08-01 12:06:58 V6 16 0 ""
4 2016-08-01 13:12:12 V6 16 1 V7
5 2016-08-01 14:04:07 V7 17 0 ""
6 2016-08-01 15:04:07 V6 17 0 ""
7 2016-08-01 17:13:16 V7 16 0 ""
8 2016-08-01 17:21:16 V7 17 0 ""
9 2016-08-01 17:21:34 V7 16 0 ""
10 2016-08-01 17:23:42 V6 16 0 ""
11 2016-08-01 17:27:16 V6 17 2 V9 V4
12 2016-08-01 17:29:28 V7 16 0 ""
Но то, что я получаю, применяя код, который вы видите выше, отличается от того, что он получает, я не знаю почему:
# A tibble: 12 x 5
DateTime Rec Ind Num_Rec Which_Rec
<dttm> <chr> <dbl> <int> <chr>
1 2016-08-01 12:04:07 V6 16 12 ""
2 2016-08-01 12:06:07 V7 17 12 ""
3 2016-08-01 12:06:58 V6 16 12 ""
4 2016-08-01 13:12:12 V6 16 12 V7
5 2016-08-01 14:04:07 V7 17 12 ""
6 2016-08-01 15:04:07 V6 17 12 ""
7 2016-08-01 17:13:16 V7 16 12 ""
8 2016-08-01 17:21:16 V7 17 12 ""
9 2016-08-01 17:21:34 V7 16 12 ""
10 2016-08-01 17:23:42 V6 16 12 ""
11 2016-08-01 17:27:16 V6 17 12 V9 V4
12 2016-08-01 17:29:28 V7 16 12 ""