按时间间隔R

时间:2018-04-26 20:26:13

标签: r join filter

我有一个数据框,其中包含跟随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,] 

}

这个问题是如果一个人在23h55点有一个点,它可能与第二天的点数比同一天更多,这就是为什么我想用一段时间在每个点附近删除这个biais。我搜索,我认为加入功能不能这样做。关于这个论坛的另一个问题,他们建议使用过滤器,我试用了我的数据。它也不完美,因为在月初和月末的分数关联可能会被联系起来,但它比白天更好......

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 :(得分:0)

对此的钝对象解决方案是首先进行笛卡尔积或交叉连接,然后进行过滤。

我可能会考虑以下内容(请注意,这不是保证运行代码,您没有提供可重现的示例)

基本上,将您的总数据分成17个子数据帧,每个大象一个。然后,得到两只大象的每一个组合。接下来,编写一个函数,该函数执行任意两个大象的笛卡尔积,并且只保留'y'大象在'x'大象的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"))