Как удалить строки во фрейме данных событий временного ряда, если другое конкретное событие не попадает в заданное пороговое значение? - PullRequest
0 голосов
/ 30 ноября 2018

Я впервые пишу здесь вопрос, поэтому заранее прошу прощения, если я поступил неправильно.сейчас я попытаюсь объяснить мою проблему и привести воспроизводимый пример.TIA

У меня есть данные, когда животные обнаруживаются в разных местах.Я хочу исключить строки из файла обнаружения (df) только для сайта A, если отдельное животное не было обнаружено на сайте B в течение периода времени (5 минут). Мне нужно повторить это для каждого отдельного животного и для нескольких сайтов .В моих реальных данных много животных и более миллиона наблюдений.Я предполагаю, что для этого понадобится как минимум два цикла.

Мне удалось найти точное время во втором кадре данных, но я не знаю, как добавить, так сказать, «порог» во времени (например, 5 минут)

Пример:

obs.num<-1:20 # a simple observation number 
animal<-c(rep("RBT 1",10),rep("RBT 2",7) ,rep("RBT 3",2),"RBT 2") # a fake list of animal id's (my data has many)
now <- Sys.time()
ts <- seq(from = now, length.out = 16, by = "mins")
ts <- c(ts,seq(from=tail(ts,1), length.out = 4, by = "hour")) # create a fake series of time stamps 
df<-cbind.data.frame(obs.num,animal,ts) # make data frame 
df$site<-c("A","B","A","B","A","B","A","B","A","B","A","B","A","B","A","B","A","B","A","B")# make a fake series of sites detection occured at 
str(df)
df # my example data frame

> df
   obs.num animal                  ts site
1        1  RBT 1 2018-11-30 15:11:38    A
2        2  RBT 1 2018-11-30 15:12:38    B
3        3  RBT 1 2018-11-30 15:13:38    A
4        4  RBT 1 2018-11-30 15:14:38    B
5        5  RBT 1 2018-11-30 15:15:38    A
6        6  RBT 1 2018-11-30 15:16:38    B
7        7  RBT 1 2018-11-30 15:17:38    A
8        8  RBT 1 2018-11-30 15:18:38    B
9        9  RBT 1 2018-11-30 15:19:38    A
10      10  RBT 1 2018-11-30 15:20:38    B
11      11  RBT 2 2018-11-30 15:21:38    A
12      12  RBT 2 2018-11-30 15:22:38    B
13      13  RBT 2 2018-11-30 15:23:38    A
14      14  RBT 2 2018-11-30 15:24:38    B
15      15  RBT 2 2018-11-30 15:25:38    A
16      16  RBT 2 2018-11-30 15:26:38    B
17      17  RBT 2 2018-11-30 15:26:38    A
18      18  RBT 3 2018-11-30 16:26:38    B
19      19  RBT 3 2018-11-30 17:26:38    A
20      20  RBT 2 2018-11-30 18:26:38    B

В этом примере я хотел бы удалить всю строку для наблюдения 19.

В моем большом наборе реальных данных я смог сделать этоидентифицировать строки / времена, когда обнаружение происходило в одно и то же время на сайте A и другом сайте, но я действительно борюсь с тем, как найти эту позицию в большом фрейме данных и как заменить% в% с некоторой болезненностью синтаксиса дляучитывать не точное, но очень близкое время (т. е. в течение 5 минут)

animals<-unique(animal)
for (i in 1:length(animals)) {

which(df[df$animals==animals[i] & df$site=="A",]$ts %in% 
df[df$animals==animals[i] & df$site=="B",]$ts)

}

Спасибо за любую помощь и, пожалуйста, спросите, могу ли я предоставить более подробную информацию / разъяснения.

Обновленный пример (я хочу иметь возможность сделать это на основе обнаружения каждого отдельного животного

В этом примере я все еще хочу, чтобы наблюдение 19 было удалено, ноответ не приведет к тому, что на основе ответа @G. Grothendieck

df[21,]<-df[19,]
df$animal<-as.character(df$animal)
df[21,"animal"]<-"RBT 4"
df[21,"site"]<-"B"
df[21,"obs.num"]<-21
df$animal<-as.factor(df$animal)
df<-df[order(df$ts),]
df

1 Ответ

0 голосов
/ 01 декабря 2018

Определите таблицу B как эти строки для сайта B, а затем присоедините df к тем строкам в B, которые удовлетворяют условию.Обратите внимание, что наблюдение 19 теперь исключено.

library(sqldf)

sqldf("with B as (select * from df where site == 'B')
  select distinct df.* from df 
  join B on df.animal = B.animal and 
            B.ts - df.ts between -5 * 60 and 5 * 60
  order by 1")

, что дает:

   obs.num animal                  ts site
1        1  RBT 1 2018-12-03 16:43:00    A
2        2  RBT 1 2018-12-03 16:44:00    B
3        3  RBT 1 2018-12-03 16:45:00    A
4        4  RBT 1 2018-12-03 16:46:00    B
5        5  RBT 1 2018-12-03 16:47:00    A
6        6  RBT 1 2018-12-03 16:48:00    B
7        7  RBT 1 2018-12-03 16:49:00    A
8        8  RBT 1 2018-12-03 16:50:00    B
9        9  RBT 1 2018-12-03 16:51:00    A
10      10  RBT 1 2018-12-03 16:52:00    B
11      11  RBT 2 2018-12-03 16:53:00    A
12      12  RBT 2 2018-12-03 16:54:00    B
13      13  RBT 2 2018-12-03 16:55:00    A
14      14  RBT 2 2018-12-03 16:56:00    B
15      15  RBT 2 2018-12-03 16:57:00    A
16      16  RBT 2 2018-12-03 16:58:00    B
17      17  RBT 2 2018-12-03 16:58:00    A
18      18  RBT 3 2018-12-03 17:58:00    B
19      20  RBT 2 2018-12-03 19:58:00    B
20      21  RBT 4 2018-12-03 18:58:00    B

Примечание

Учитывая, что в примере в вопросе произошли изменения, которые следует прояснить, мыиспользовал это в примере выше:

obs.num<-1:20 # a simple observation number 
animal<-c(rep("RBT 1",10),rep("RBT 2",7) ,rep("RBT 3",2),"RBT 2") # a fake list of animal id's (my data has many)
now <- Sys.time()
ts <- seq(from = now, length.out = 16, by = "mins")
ts <- c(ts,seq(from=tail(ts,1), length.out = 4, by = "hour")) # create a fake series of time stamps 
df<-cbind.data.frame(obs.num,animal,ts) # make data frame 
df$site<-c("A","B","A","B","A","B","A","B","A","B","A","B","A","B","A","B","A","B","A","B")# make a fake series of sites detection occured at 
df[21,]<-df[19,] 
df$animal<-as.character(df$animal) 
df[21,"animal"]<-"RBT 4" 
df[21,"site"]<-"B" 
df[21,"obs.num"]<-21 
df$animal<-as.factor(df$animal) 
df<-df[order(df$ts),]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...