あるデータフレームに大きな時系列full
があり、別のデータフレームにタイムスタンプのリストがありtest
ます。full
のタイムスタンプを囲むデータポイントでサブセット化する必要がありtest
ます。私の最初の本能(R noobとして)は以下を書くことでしたが、それは間違っていました
subs <- subset(full,(full$dt>test$dt-i) & (full$dt<test$dt+i))
結果を見ると、Rが両方のベクトルを同時にループして間違った結果を出していることがわかりました。私のオプションは、次のようなループを作成することです。
subs<-data.frame()
for (j in test$dt)
subs <- rbind(subs,subset(full,full$dt>(j-i) & full$dt<(j+i)))
ループを実行するためのより良い方法があるかもしれないと私は感じます、そしてこの記事は私たちにRループをできるだけ避けるように懇願します。もう1つの理由は、これが最適化アルゴリズムの中心となるため、パフォーマンスの問題に直面する可能性があることです。教祖からの提案は大歓迎です。
編集:
これは、間違ったアプローチと、機能するがより良い可能性のあるアプローチを示す再現可能なコードです。
#create a times series
full <- data.frame(seq(1:200),rnorm(200,0,1))
colnames(full)<-c("dt","val")
#my smaller array of points of interest
test <- data.frame(seq(5,200,by=23))
colnames(test)<-c("dt")
# my range around the points of interset
i<-3
#the wrong approach
subs <- subset(full,(full$dt>test$dt-i) & (full$dt<test$dt+i))
#this works, but not sure this is the best way to go about it
subs<-data.frame()
for (j in test$dt)
subs <- rbind(subs,subset(full,full$dt>(j-i) & full$dt<(j+i)))
編集:ユースケースをより適切に反映するように値を更新しましたが、@mrdwabのソリューションが予想外に大幅に進んでいることがわかりました。
@mrdwabのベンチマークコードを使用しています。初期化は次のとおりです。
set.seed(1)
full <- data.frame(
dt = 1:15000000,
val = floor(rnorm(15000000,0,1))
)
test <- data.frame(dt = floor(runif(24,1,15000000)))
i <- 500
ベンチマークは次のとおりです。
test replications elapsed relative
2 mrdwab 2 1.31 1.00000
3 spacedman 2 69.06 52.71756
1 andrie 2 93.68 71.51145
4 original 2 114.24 87.20611
まったく予想外。心=吹き飛ばされた。誰かがこの暗い隅に光を当てて、何が起こっているのかを教えてくれませんか。
重要:@mrdwabが以下に示すように、彼のソリューションは、ベクトルが整数の場合にのみ機能します。そうでない場合、@spacedmanは正しい解決策を持っています