[英]How to merge/join dataframes in R conditionally to dynamic time intervals
[英]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.