簡體   English   中英

按時間間隔R加入數據幀

[英]Join dataframes by time intervals R

我有一個數據框,上面有個人,后面跟着GPS項圈。 為了檢查這些人是否獨立於運動或彼此跟隨,我想將一個人的每個點(每一行)與該第一點前后12小時間隔的其他人的每個點相關聯,然后計算例如,它們間隔不到100 m的頻率。

我的數據框: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

首先,我嘗試按Date進行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小時)相關聯嗎? 如果可能的話,請不要嘗試,因為我們在月底和月初仍然有偏差的值。

預先感謝您的幫助! :)

對此的鈍對象解決方案是首先執行笛卡爾積或交叉連接,然后進行過濾。

我可能會考慮以下內容(請注意,這不是保證運行的代碼,您沒有提供可復制的示例)

本質上,將您的總數據分成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"))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM