Присоединение данных к временным интервалам R - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть датафрейм с людьми, за которыми следуют ошейники GPS. Чтобы проверить, являются ли эти люди независимыми в их движениях или они следуют друг за другом, я хочу связать каждую точку (каждый ряд) одного человека с каждой точкой других людей, которые находятся в 12-часовом интервале вокруг этой первой точки, а затем вычислить например, как часто они находятся на расстоянии менее 100 м друг от друга.

Мой фрейм данных: Data_real

 'data.frame':  57471 obs. of  7 variables:
$ Elephant         : Factor w/ 17 levels "Bull","Bull (one tusk)",..: 1 1 1 1 1 
$ Date.time        : POSIXct, format: "2015-10-06 14:38:00" "2015-10-06 18:37:00" "2015-10-06 22:37:00" "2015-10-07 02:37:00" ...
$ Date        : POSIXct, format: "2015-10-06" "2015-10-06"
$ Date_month       : chr  "2015-10" "2015-10" "2015-10" "2015-10" ...
$ Date.time_plus6h : POSIXct, format: "2015-10-06 20:38:00" "2015-10-07 
$ Date.time_minus6h: POSIXct, format: "2015-10-06 08:38:00" "2015-10-06 
$ coords.x1        : num  329468 329393 328341 327563 327271 ...
$ coords.x1.1      : num  329468 329393 328341 327563 327271 ...


Elephant             Date.time coords.x1 coords.x1.1 Date_month    Date.time_plus6h   Date.time_minus6h
0     Bull 2015-10-06 14:38:00  329467.6    329467.6    2015-10 2015-10-06 20:38:00 2015-10-06 08:38:00
1     Bull 2015-10-06 18:37:00  329392.5    329392.5    2015-10 2015-10-07 00:37:00 2015-10-06 12:37:00
2     Bull 2015-10-06 22:37:00  328341.3    328341.3    2015-10 2015-10-07 04:37:00 2015-10-06 16:37:00
3     Bull 2015-10-07 02:37:00  327562.9    327562.9    2015-10 2015-10-07 08:37:00 2015-10-06 20:37:00
4     Bull 2015-10-07 06:37:00  327271.0    327271.0    2015-10 2015-10-07 12:37:00 2015-10-07 00:37:00
5     Bull 2015-10-07 14:38:00  322977.5    322977.5    2015-10 2015-10-07 20:38:00 2015-10-07 08:38:00

Сначала я пытался выполнить inner_join по дате, а затем вычислить расстояние между каждой соединенной точкой.

Association<-NA
for (id in unique(Data_real$Elephant)) {
id1<-Data_real[Data_real$Elephant == id,] #one individual
id2<-Data_real[Data_real$Elephant != id,] #all the others

all.id<-inner_join(id2,id1,by="Date")
deltaX<-(all.id$coords.x2.y - all.id$coords.x2.x) ^ 2   
deltaY<-(all.id$coords.x1.y - all.id$coords.x1.x) ^ 2
all.id$distance<-sqrt (deltaX + deltaY) #distance in meters 

Association1<-rbind(Association1, all.id) 

Data_real<-Data_real[Data_real$Elephant != id,] 

}

Проблема в том, что если у человека есть точка, например, в 23 ч 55, она может быть больше связана с точками следующего дня, чем в тот же день, поэтому я хочу использовать интервал времени вокруг каждой точки, чтобы убери это предубеждение. Я ищу и думаю, что функция соединения не может этого сделать. На другом вопросе этого форума они предлагают использовать фильтр, который я пробовал на своих данных. Это также не идеально, потому что связь точек в начале и конце месяца может быть предвзятой, но лучше, чем днем ​​...

all.id<-inner_join(id2,id1,by="Date_month")
all.id<-as_tibble(all.id)
all.id2<-filter(all.id,Date.time.y >= Date.time_moins6.x & Date.time.y <= 
Date.time_plus6.x) 

Основная проблема в том, что кажется, что команда работает не так, как я ее кодировал, или она слишком длинна для завершения.

Я читал на разных форумах и обнаружил, что функции в пакете data.table могут работать на меня, но все же я не понимаю, как, и я не уверен, что это для той же манипуляции.

Итак, мой вопрос: хороший ли у вас теперь способ объединить два фрейма данных, чтобы вы хотели связать каждую точку одного индивида с каждой точкой всех других индивидов, которые составляют + 6 / -6 часов относительно времени этой первой точки ? Если возможно, не так, как я пытался, потому что у нас все еще есть предвзятое значение в конце и начале месяца.

Заранее спасибо за помощь! :)

1 Ответ

0 голосов
/ 27 апреля 2018

Решение тупого объекта - сначала сделать декартово произведение или перекрестное соединение, затем отфильтровать.

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

По сути, разделите ваши общие данные на 17 подкадров данных, по одному на каждого слона. Затем получите каждую комбинацию двух слонов. Затем напишите функцию, которая делает декартово произведение любых двух слонов и сохраняет только те строки, где слон «у» находится в пределах 6-часового окна слона «х». Используйте map2, чтобы передать пары слонов и связать их вместе. Теперь мы отфильтровали данные, чтобы у нас не было фактических данных о положении, поэтому нам нужно снова объединить оставшиеся данные. Тогда вы можете делать все остальное, что вы собирались сделать.

library(dplyr)
each_elephant = split(Data_real,Data_real$Elephant)
pairs = expand.grid(x = levels(Data_real$Elephant), 
                    y = levels(Data_real$Elephant))
fuzzyJoin = function(e1,e2){
  df1 = each_elephant[[e1]] %>% select("Elephant.x" = Elephant,
                       "Date.time.x" = Date.time,
                       Date.time_plus6h,
                       Date.time_minus6h)
  df2 = each_elephant[[e2]] %>% select("Elephant.y" = Elephant,
                       "Date.time.y" = Date.time)
  totalDF = tidyr::crossing(df1,df2)
  totalDF %<>%
    filter(Date.time.y >= Date.time_minus6h & Date.time.y <= Date.time_plus6h)
  return(totalDF)
}
output = do.call(bind_rows,purrr::map2(pairs$x,pairs$y,fuzzyJoin)) %>%
  left_join(Data_real, by=c("Elephant.x"="Elephant","Date.time.x"="Date.time")) %>%
  left_join(Data_real,by=c("Elephant.y"="Elephant","Date.time.y"="Date.time"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...