前置き
R wizard な皆様でしたら一瞬で書けるようなコードかもしれませんが、ここらへんのアルゴリズムなんて情報処理の授業で聞いて20年経過していてすっかり忘却していて数時間かかってしまいました、、のコードです。
目的
行動情報のDF(ma.df_eff)と位置情報のDF(gps.df)があり、それぞれ全く別の粒度で日時を文字列で持っている場合に、JOIN(片方のDFにもう片方のカラムを結合)させます。
おススメ(NN法を使用)
RANNというライブラリはANN("nn"とありますがニューラルネット一派ではなくn近傍)をC++実装したライブラリをRに移植したものです。nn2()を使用すると近傍ソートが高速に行えるのと、INPUT/OUTPUTをそれぞれベクトルで渡せます。
library(RANN)
#基準時間を決めておきます
base_datetime <- as.POSIXct(min(ma.df_eff$startDate))
#比べるベクトル(elapsed_time、経過時間)を作成
ma.df_eff$elapsed_time <- as.numeric(difftime(as.POSIXct(ma.df_eff$startDate),base_datetime,units = "secs"))
gps.df$elapsed_time <- as.numeric(difftime(as.POSIXct(gps.df$startDate),base_datetime,units = "secs"))
#近傍の算出
nearest <- nn2(gps.df$elapsed_time, ma.df_eff$elapsed_time, k=1)
#近傍値の挿入
ma.df_eff$latitude <- gps.df$latitude[nearest[['nn.idx']]]
ma.df_eff$longitude <- gps.df$longitude[nearest[['nn.idx']]]
いまいち版(which.minをループ)
とりあえず書いたけどコレジャナイとモヤっていたコードです。多分DFが数万行同士とかになった瞬間に爆死します。
近傍を探すところのみ抜粋
ma.df_eff$latitude2 <- 0
ma.df_eff$longitude2 <- 0
for(i in 1:nrow(ma.df_eff)){
ma.df_eff$latitude2[i] <- gps.df$latitude[which.min(abs(ma.df_eff$elapsed_time[i]-gps.df$elapsed_time))]
ma.df_eff$longitude2[i] <- gps.df$longitude[which.min(abs(ma.df_eff$elapsed_time[i]-gps.df$elapsed_time))]
}