WeeklyAlteryxTips#31 文字列型フィールド内の値が数値かどうか判断する

Alteryx

今回は、文字列フィールドの中で、数値型のレコードだけ判定する方法を考えてみたいと思います。

例えば以下のようなデータを考えてみます。

この中でappleは完全に文字列ですが、それ以外は数値型として取り扱いデータです。一見してIs関数で抽出できそうですが、実は一筋縄では行きません。

よくやりがちな失敗パターン

例えば、関数リストを眺めていると、以下のような関数でできそうに思うかもしれません。

IsNumber(ToNumber([String]))

結果は以下のとおりです。

これは、ToNumber関数でStringフィールドを数値に変換するわけですが、IsNumber関数がデータの型を判定するため失敗します。つまり、「apple」はToNumber関数で数値型になりますが、値はNullとなります。その後、IsNumber関数がデータ型自体を判定するため、数値型ということになり、結論としてはTrueとして判定してしまうためです。

数値として判定する方法

3つご紹介します。2番目の方法は、Designer Cloudなどで有効に使えそうな方法です。

ToNumberを使った方法

IsNumberではフィールドの型自体を判断するとのことなので、それではToNumberで変換したときにNullになっているものあればIsNullで判定できないのか?ということでやってみましょう。

!IsNull(ToNumber([String]))

数値に変換してNullでなければ数値型という意味になります。結果は以下の通りで、思ったのと違う結果になっています。

なぜ「apple」がTrueになってしまうのか。これはToNumberで数値型に変換したときに、文字列は「0」という結果を出力するためです。ただし、「1,000」は数値として認識してくれています。

しかしこれ、よくよく見ると、いくつかオプションがあることがわかります。

bIgnoreErrors、keepNulls、decimalSeparetorというオプションがあることがわかります。ただ、fxボタンから関数をそのまま選択しても、これらのオプションは自動で挿入されません。

これらの意味は以下のとおりです。

  • bIgnoreErrors

エラーを無視するようになるオプションです。デフォルトでは「情報を失いました」と表示が出るので意図的にやっているのであれば、Trueにした方が無駄な表示を消すことができます。

  • keepNulls

数値に変換できない場合、False(デフォルト)では0を出力しますが、TrueにするとNullを出力するようになります。

  • decimalSeparator

3桁区切り記号を指定できます。これを指定すれば、その記号は区切り記号として認識してくれ、正常に数値に変換できます。

つまり、

!IsNull(ToNumber([String],"True","True",","))

という関数で判定が可能になります。

これにより、以下のような結果が得られます。

セレクトツールで数値型に変換してからNullになっているかどうかで判定する方法

一度セレクトツールで数値型(Double)に変換してみると、文字列はNullになるためセレクトルールで変換後にIsNull関数でNullになっているかどうかで、文字列なのか数字なのかを判定することが可能です。3桁ごとの区切り文字がある場合は、これはセレクトツールでは文字列として判断してしまうため、あらかじめReplace関数で空白に置換しておくとこのようなものにも対応可能です。つまり、以下のようなワークフローになります。

※フォーミュラツール内のIsEmpty関数でもIsNull関数でも結果は同じです

最初のフォーミュラツール:

セレクトツール:

最後のフォーミュラツール:

これにより、以下のような結果になります。

正規表現で判定

例えば、以下のような正規表現式で表すことができます。

^[+\-]*[\d,]+\.*\d*$

これは、以下のような条件で判定しています。

  • 行頭から行末まで数値であるかどうか
  • 頭に(半角の)+、-の符号がついていてもOK
  • 小数点があってもOK
  • 小数点以降の数字があってもなくてもOK
  • 3桁ごとの区切り記号があってもOK(ただし、正確に3桁ごとに区切られているかどうかは判定しておらず、区切り記号があってもOKとして判断)

ただし、「+,.」などはTrueとして返してしまいます。何を優先して判断したいか、で正規表現の内容を変えることができるので、色々工夫してみてください。もしくは、IF文などを使って少なくとも数字を含んでいないといけない、などの条件を別途付け加えることもできます。

なお、正規表現ツールを使う場合は、以下のような設定となります。

正規表現はシンプルに表現できますが、慣れていないと難しいため最初に紹介した複数ツールを組み合わせた方法の方が確実にワークフローを構築できる可能性があります。

ロケールの影響

ところで、ロケール(地域)によっては、このままでは失敗します。つまり、フランスを中心とした国々では、小数点を示すピリオドがカンマになっています。逆に、そのような国では3桁の区切り記号がピリオドになります。ですので、この方法は国によって若干のアレンジが必要になります。グローバルのデータを扱う場合はご注意ください。

まとめ

  • 文字列フィールドから各レコードが数値かどうかを判断する方法をご紹介しました
  • 方法としては、IsNull+ToNumber、セレクトツール+IsNull/IsEmptyで判断後結合ツールで結果を結合するか、正規表現を使う方法があることを紹介しました。
  • ロケールにも注意してください(フランス式の場合はピリオドとカンマが入れ替わります)

サンプルワークフローダウンロード

次回

しばらく関数シリーズで行きたいと思います。

コメント

タイトルとURLをコピーしました