2015年4月9日木曜日

Rで最上位桁を取り出す

なんでこんなことをしたいのかは、また別の機会に書くとして、やりたいのは数字の最上位桁の数字を取り出したいというものです。123だったら1、31415だったら「3」を取り出すという感じです。

整数商を使えばいけそうです。123から1を取り出すには100で割る、31415から3を取り出すには10000で割る。

  123 ÷  100 = 1 余り  23

 31415 ÷ 10000 = 3 余り 1415

割る数は、10×(桁数-1)ですね。↓こんな感じでしょうか。

n <- floor(log10(x)) # 桁数-1
msd <- x %/% 10^n    # 整数商


ちなみに、MSDというのはMost Significant Digit(最上位桁、最上位の数字)の略です。

正しく結果が出ているか、乱数で確認してみましょう。

set.seed(1) # 再現性のために
x <- sample(1:1000000, 20)

n <- floor(log10(x)) # 桁数-1
msd <- x %/% 10^n    # 整数商

data.frame(x, msd) # 並べて比較するためにデータフレームに

        x msd
1  265509   2
2  372124   3
3  572853   5
4  908206   9
5  201682   2
6  898386   8
7  944670   9
8  660794   6
9  629110   6
10  61786   6
11 205973   2
12 176555   1
13 687015   6
14 384099   3
15 769831   7
16 497692   4
17 717608   7
18 991890   9
19 380029   3
20 777431   7


うまくいっているようですね。

でも、最上位桁を求めるために、常用対数とfloorと整数商を動員するのか。なんだか仰々しいというか。

要は1文字目を取り出せばいいんでしょ、ってところは後から気づきました。

↓文字列型に変換して、1文字目を取り出して、それを整数型に変換する、という考え方です。このほうがシンプルですね。

msd2 <- as.integer(substr(as.character(x), 1, 1))

data.frame(x, msd, msd2)

        x msd msd2
1  265509   2    2
2  372124   3    3
3  572853   5    5
4  908206   9    9
5  201682   2    2
6  898386   8    8
7  944670   9    9
8  660794   6    6
9  629110   6    6
10  61786   6    6
11 205973   2    2
12 176555   1    1
13 687015   6    6
14 384099   3    3
15 769831   7    7
16 497692   4    4
17 717608   7    7
18 991890   9    9
19 380029   3    3
20 777431   7    7


うん、同じ結果になりました。

タイプ数は大して変わりませんが、ロジックがシンプルな分、後者の方がいいような気がしますね。

ちなみにas.characterは省略できる(勝手に文字列として解釈してsubstrを適用してくれる)みたいですが、私は書いておく派ですね。




0 件のコメント:

コメントを投稿