2015/04/05

R マイナーな演算子 %in% で期間の重なりチェック

[R]
昨日は使いませんでしたが PostgreSQL には範囲型があるので、期間の重なりチェックが簡単。一方、たまに R で同様のことが必要になると、一時的に期間内の全日付をベクトルにして %in% 演算子を使ってきました。例えば ↓ のように。

days1 = seq(as.Date('2015-03-10'), as.Date('2015-04-10'), 'days')
days2 = seq(as.Date('2015-03-30'), as.Date('2015-04-30'), 'days')

print(any(days1 %in% days2))


seq 関数で期間中の全日付を発生させて二つのベクトル days1, days2 に入れ、%in% 演算子で days1 の各要素が days2 に存在するかチェックし、一つでも存在したら TRUE になるよう any 関数でまとめています。↓ で %in% 演算子を知りました。

■ R-help mailing list : merging data sets to match data to date

ドキュメントの Operator Syntax and Precedence を見ると %any% が special operators となっていて、% と % の間に何か挟むと特別な演算子にできるようですが、詳しい説明がないのでよく分かりません。%in% 自体はドキュメントに載ってなく、↓ が参考になります。

■ How did I do that??? : The %in% operator in R
I have recently discovered the %in% operator in R, and have been surprised at the lack of online documentation for this simple, yet SUPER USEFUL, operator.


今日調べた範囲では、日本語のウェブページで %in% 演算子のサンプルが見当たらなかったので、以下に簡単な例を紹介。実行環境は Windows 7 32bit + R Portable 3.1.2 です。冒頭のコードでは日付型に使いましたが、数値や文字でも同様にできます。

(nums1 = 1:15)
(nums2 = 10:20)
nums1 %in% nums2
any(nums1 %in% nums2) # 上で一つでも TRUE があれば TRUE


↑ のように、A %in% B を入力するとベクトル A の要素一つ一つが B に存在するかを調べ、A と同じ要素数の真偽型ベクトルが返ります。下は二つの文字列を比較して共通文字をチェックする例。

(chars1 = unlist(strsplit('東京千葉埼玉神奈川', '')))
(chars2 = unlist(strsplit('大阪京都兵庫奈良', '')))
chars1 %in% chars2


対象とする数値範囲や期間が長いほどベクトルの要素数が増えて遅くなりますが、範囲(期間)の先頭・末尾を比較する条件式を組み合わせると自分はうっかり間違いかねないので、この %in% 演算子一つで済ませることが多いです。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。