Rで大きい・等しい・小さいを一度に判定

Rには比較演算子<=>がない
R
公開

2022年12月28日

例えば、次のようなdata frameがあるとします。

df <- data.frame(col1=1:10, col2=c(12:8, 6, 7, 5:3))
df
   col1 col2
1     1   12
2     2   11
3     3   10
4     4    9
5     5    8
6     6    6
7     7    7
8     8    5
9     9    4
10   10    3

これが1データ1行のdata frameだったとして、各データ内のcol1とcol2の値を比較して、

を知りたい場合、どういうコードを書いたらいいでしょうか。

比較演算子<=>

Perlなどの言語を使ったことがある方なら、比較演算子<=>を使いたいと考えるでしょう。 <=>は大小と等しさを一度に判定できる演算子です。

a <=> bと書いたとき、

  • a < b ならば -1
  • a = b ならば 0
  • a > b ならば 1

が返ってきます。

しかしRにはこの比較演算子がありません。

sign関数を利用する

Rでa <=> bと同じことをするならばsign関数を使うのが簡単です。

sign(a - b)

このように書けば比較演算子<=>と同じ戻り値を得られます。先ほどのdata frameで試してみましょう。

sign(df$col1 - df$col2)
 [1] -1 -1 -1 -1 -1  0  0  1  1  1

これを使えば最初に知りたかった数をカウントできますね。

table(sign(df$col1 - df$col2))

-1  0  1 
 5  2  3 

値の並べ替えについて

比較演算子<=>は上のように直接使われることはあまりありません(筆者は仕事で直面しましたが)。 値の並べ替えを行うときに、値の大小関係をソート関数に与えるために使うことが多いと思います。

Rでそういう場面は出てこないのでしょうか。並べ替えと言えばsortorderといった関数が思い浮かびますが、 もしも単純に比較できないオブジェクト、例えばdata frame同士を並べ替えたいときに比較演算子を使いたくならないのでしょうか。

調べてみたら、Rのやり方はなかなか面白かった。 xtfrm関数にリスト的な(配列的な)オブジェクトを渡すと、それをintegerで表現したベクトルが返ってきてそのベクトルをソートするというやり方でした。 ということで独自のソート関数を作りたい場合はxtfrmのS3メソッドを作ればよいということですね。まあ、ほぼ需要なさそうか・・・