Tableau Prepの作業を変えるTips集13 ー文字列の処理、正規表現ー
Tableau Prepユーザー会のNakajima2です。
Japan Preppin Data FamメンバーのPrep Tips集をご紹介します。
Preppin Data勉強会でも、みなさんのフローにちょこちょこ登場する文字列の処理。比較的に使い慣れている方が多く深い議論になるケースが少ないかなとも感じますが、特定の文字列を 1)見つける、2)置き換える、3)分割する 作業は利用回数多く、実務でも頻繁に対応している操作ではないかと思います。
今回は、この3つの作業を中心に、まとめてみました。
Prep Tips (25) : 文字列の処理
まずは、関連する文字列の関数をまとめてみます。
いっぱいありますね、、
1)見つける
CONTAINS
構文 : CONTAINS(string, substring)
出力ブール値定義指定された文字列に指定された部分文字列が含まれている場合、true を返します。
例 : CONTAINS("Calculation", "alcu") = true
ENDSWITH
構文 : ENDSWITH(string, substring)
出力ブール値定義特定の文字列が指定されたサブ文字列で終わる場合は、true を返します。行末の空白は無視されます。
例 : ENDSWITH("Tableau", "leau") = true
STARTSWITH
構文 : STARTSWITH(string, substring)
出力ブール値定義string が substring で始まる場合は、true を返します。先頭の空白は無視されます。
例 : STARTSWITH("Matador, "Ma") = TRUE
FIND
構文 : FIND(string, substring, [start])出力数値定義
文字列内の部分文字列のインデックス位置を返します。部分文字列が見つからない場合は 0 を返します。文字列の最初の文字の位置は 1 です。
オプションの数値引数 start を追加した場合、関数は開始位置より前に出現する部分文字列のインスタンスをすべて無視します。
例 : FIND("Calculation", "alcu") = 2
FIND("Calculation", "Computer") = 0
FIND("Calculation", "a", 3) = 7
FIND("Calculation", "a", 2) = 2
FIND("Calculation", "a", 8) = 0
FINDNTH
構文 : FINDNTH(string, substring, occurrence)
出力数値定義指定した文字列内の部分文字列が n 番目に現れる位置を返します。ここで、n は引数 occurrence によって定義されます。
例 : FINDNTH("Calculation", "a", 2) = 7
注 : FINDNTH はすべてのデータ ソースで使用できるわけではありません。
LEFT
構文 : LEFT(string, number)
出力文字列定義文字列の左端から <number> 個の文字を返します。
例 : LEFT("Matador", 4) = "Mata"
MID
構文 : (MID(string, start, [length])
出力文字列定義
指定された start 位置から始まる文字列を返します。文字列の最初の文字の位置は 1 です。
オプションの数値引数 length を追加した場合、返される文字列には、その引数に相当する数の文字だけが含まれます。
例 : MID("Calculation", 2) = "alculation"
MID("Calculation", 2, 5) ="alcul"
RIGHT
構文 : RIGHT(string, number)
出力文字列定義文字列の右端から <number> 個の文字を返します。
例 : RIGHT("Calculation", 4) = "tion"
2)置き換える
LOWER
構文 : LOWER(string)
出力文字列定義指定された <string> をすべて小文字にして返します。
例 : LOWER("ProductVersion") = "productversion"
UPPER
構文 : UPPER(string)
出力文字列定義指定された <string> をすべて大文字にして返します。
例 : UPPER("Calculation") = "CALCULATION"
PROPER
構文 : PROPER(string)
出力文字列定義
指定された <string> を各単語の最初の文字を大文字、残りの文字を小文字にして返します。
例 : PROPER("PRODUCT name") = "Product Name"
PROPER("darcy-mae") = "Darcy-Mae"
注 : スペースや句読点などの英数字以外の文字も区切り文字として扱われます。
TRIM
構文 : TRIM(string)
出力文字列定義指定された <string> を、先頭と末尾の空白を削除して返します。
例 : TRIM(" Calculation ") = "Calculation"
LTRIM
構文 : LTRIM(string)
出力文字列定義指定された <string> を先頭の空白を削除して返します。
例 : LTRIM(" Matador ") = "Matador "
RTRIM
構文 : RTRIM(string)
出力文字列定義指定された <string> を末尾の空白を削除して返します。
例 : RTRIM(" Calculation ") = " Calculation"
REPLACE
構文 : REPLACE(string, substring, replacement)
出力文字列定義<string> で <substring> を検索し、それを <replacement>で置き換えます。<substring> が見つからない場合、文字列は変更されません。
例 : REPLACE("Version 3.8", "3.8", "4x") = "Version 4x"
3)分割する
SPLIT
構文 : SPLIT(string, delimiter, token number)
出力文字列定義指定した文字列を基に、区切り文字を使用して連続したトークンに文字列を分割したサブストリングを返します。
例 : SPLIT ("a-b-c-d", "-", 2) = "b"
SPLIT ("a|b|c|d", "|", -2) = "c"
注
文字列は区切り文字とトークンが交互に連続する文字列として解釈されます。そのため、文字列が abc-defgh-i-jklで、区切り文字が「-」の場合、トークンは (1) abc、(2) defgh、(3) i、(4) jlk になります。
SPLIT はトークン番号に対応するトークンを返します。トークン番号が正の場合、トークンは文字列の左端からカウントされます。トークン番号が負の場合、トークンは文字列の右からカウントされます。
活用事例
Preppin Data 2024Week17 のデータを利用して説明します。
(この課題は、Preppin Data 勉強会でも取り上げていますので、背景など概要はリンク先をご覧ください)
データソースにスーパーマーケットの月別実績データがまとめられており、各月のデータはワークシートに別れています。下記のデータは、データソース接続時に各ワークシートをユニオンで縦に並べたデータになっています。
(今回の事例では、必要最低限の2つのフィールドに保持したものにしています)
業務でもちょくちょく見かけるファイル名やワークシート名に月名の情報が入っているもの。ユニオンの作業で、[Table Names] としてワークシート名がデータとして利用出来る状況になっています。
[Table Names]. のデータを、1)見つける、2)置き換える、3)分割する の組み合わせで、最終的に月名にする作業の代表例です。
1)REPLACE
REPLACE関数でデータ中の文字列 ’Month-’ を '' (データがないもの)に置き換えて、月名のみ残す操作です。
2)SPLIT
SPRIT関数で、データ中の文字列 '-' を利用してデータを文字列を分割し、'-' の後ろ(最後の1つ)の文字列を取り出す操作です。
2)UI利用 ー値の分割 を利用するー
Prepに実装されているUIを利用して、文字列の分割を行うことが出来ます。ネイティブ機能なので、とても使いやすく便利です。
上記の操作で、月名のみの文字列になります。フローで自動生成された関数を確認すると、下記の通りとなっています。SPRIT関数が利用されていますが、2)の例とちょっと違っています。
上記3種の出力結果は、次の通りです。全て同じ値になっていますね。
ファイル名やワークシート名から日付データを取り出す際も同様な操作で文字列を取り出すことが出来ます。
知っていると実用的なTipsです。
Prep Tips (26) : 正規表現の利用
文字列を1)見つける、2)置き換える の別手法として、正規表現を利用した方法があります。
正規表現はちょっと難しいけど、やり方覚えておくととても便利!
今は生成AIが利用出来るので、正規表現の部分はAIに教えてもらうのが良いです。複雑な文字列検索も正規表現を利用するとシンプルな短い関数で記載出来、とても有用です。
まずは、対応している関数一覧から。関数の詳細説明は、Tableauのマニュアルをご参照ください。
REGEXP_REPLACE(string, pattern, replacement)
正規表現のパターンが置換文字列に置き換えられている特定の文字列のコピーを返します。
Tableau データ抽出では、パターンおよび置換を定数にする必要があります。
例 : REGEXP_REPLACE('abc 123', '\s', '-') = 'abc-123'
REGEXP_MATCH(string, pattern)
指定した文字列のサブストリングが正規表現パターンに一致した場合に true を返します。
Tableau データ抽出では、パターンを定数にする必要があります。
例 : REGEXP_MATCH('-([1234].[The.Market])-','\[\s*(\w*\.)(\w*\s*\])')=true
REGEXP_EXTRACT(string, pattern)
正規表現のパターンと一致する文字列の一部を返します。
Tableau データ抽出では、パターンを定数にする必要があります。
例 : REGEXP_EXTRACT('abc 123', '[a-z]+\s+(\d+)') = '123'
REGEXP_EXTRACT_NTH(string, pattern, index)
正規表現のパターンと一致する文字列の一部を返します。部分文字列は n 番目 (n は指定されたインデックス) のキャプチャリング グループと照合されます。index が 0 の場合、文字列全体が返されます。
Tableau データ抽出では、パターンを定数にする必要があります。
例 : REGEXP_EXTRACT_NTH('abc 123', '([a-z]+)\s+(\d+)', 2) = '123'
活用事例 1)
先ほどと同様に、Preppin Data 2024Week17 のデータを利用して説明します。
(この課題は、Preppin Data 勉強会でも取り上げていますので、背景など概要はリンク先をご覧ください)
データソースにスーパーマーケットの年度予算データがあります。
[Budget] のフィールドが数値と文字が混在しています。これを分離し以後のフローで利用出来るデータ形式にする必要があります。
正規表現の利用例として、文字の削除 と 数値の削除 を正規表現を利用して作成してみます。
まずは、文字の削除 から。
続いて、数値の削除 です。
上記の結果は下図の通りです。
普通のREPLACE関数を利用しても、同様な結果が得られます。
活用事例 2) 複数の文字列を 見つける、置き換える
Preppin Data FamメンバーのNakamuraさんからのTipsです。
正規表現が有効に使えるのは、複数の文字列を検索し、一度に文字列を置き換える操作をするケースです。
次の事例で、CONTAINS関数を複数使い構成する式を、正規表現を利用しシンプルにまとめる方法を説明します。結構便利なので是非使ってみてください。
(事例)ー条件式 IF 分を利用ー
[科目] フィールドにある”数学"と"科学"と"物理"のデータに対し"理数系"と表示させ、他の科目は "文系"と表示させる
活用事例 3) 正規表現を生成AIで関数作成する
正規表現は覚えるのがちょっと大変。生成AIを利用すれば、関数を作成してもらえいます。たまに間違えることあるようですが、AIの利用で作業効率を向上できます。
以下は、Chat GPT-4o で、上記2)事例の正規表現を表示させた例になります。
GPTへの質問内容(Prompt)
ChatGPT 解答
Tableau Prepで正規表現を利用して特定の科目を分類するための計算フィールドを作成するには、以下の計算式を使用します。
Tableau Prepを開き、データフローにデータソースを追加します。
データクリーニングステップを追加し、新しい計算フィールドを作成します。
次の計算式を入力します。
IF REGEXP_MATCH([科目], "数学|科学|物理") THEN
"理数系"
ELSE
"文系"
END
この計算式の説明:
REGEXP_MATCH([科目], "数学|科学|物理") は、[科目] フィールドの値が "数学"、"科学"、または "物理" のいずれかに一致するかどうかをチェックします。
一致する場合は "理数系" を返し、それ以外の場合は "文系" を返します。
これで、[科目] フィールドの値に基づいて "理数系" または "文系" を表示させることができます。
おわりに
文字列の各種処理は、いろいろな場面で多く出てくるものになります。データ前処理 クリーニングでは対応必須事項です。
便利なTipsも多くあり、今回だけでは説明しきれない点もまだまだあります。
改めての機会に、Tipsでご紹介できればと思っています。