JMPスクリプト言語の最も一般的な用途は、作業の自動化です。次に多いのは、JMPウィンドウから結果を抽出することです。これは簡単に実行できますが、残念ながら、初心者にはスクリプトでどのように実行すればよいのか分かりにくいものです。ここでは、統一された表示オブジェクトモデルを用いたウィンドウの構成について説明します。次に、任意のウィンドウ内の任意のコンテンツへの参照方法を示します。最後に、いくつかの代替アドレス形式を示します。
特にXPathクエリ言語について解説します。JMP開発用のユニットテストスクリプトを作成する際に開発した、分かりやすく実践的な例を交えながら、詳細な背景情報も解説します。また、JMPコンテンツへのアクセスをより簡単で使いやすくするインタラクティブなJMPツールや、ベストプラクティスも紹介します。JMPの結果から必要な情報を得るための最適な方法をご紹介します。
こんにちは。マーク・ベイリーです。同僚のタニヤ・マルドンと一緒に登壇します。今回のプレゼンテーションのタイトルは「見えるけど、どうやって取得するの?」です。よくある状況についてお話しします。JMPは様々なウィンドウに様々な結果を生成しますが、ある時点で分析を自動化したり、表示をカスタマイズしたり、変更したり、あるいは更なる計算のために情報を抽出したりしたいと考えるかもしれません。そこで、いくつかの疑問が浮かび上がります。どうすればいいのでしょうか?これらの結果にアクセスする仕組みはあるのでしょうか?役立つツールはあるのでしょうか?最後に、JMPスクリプトを25年近く使ってきた経験から、この目的のためのベストプラクティスはあるのでしょうか?
プレゼンテーションの本題に入る前に、一言コメントさせてください。JMPでは、いつでもプラットフォーム用のスクリプトを保存できます。画面に加えた変更は、プラットフォーム起動スクリプトの「ディスプレイに送信」引数を使用して自動的に記録されます。このスクリプトは、将来、分析と結果を再現したいときに実行できます。
この「ディスプレイに送信」引数は、JMPがこれらの変更を記録できるようにするために考案されたメカニズムですが、スクリプト作成を目的としたものではありません。JMPに搭載されている、まさにベストプラクティスとなるテクニックをご紹介します。
まず最初に理解していただきたいのは、JMPのウィンドウを見ているとき、実際には連携して動作する2つのオブジェクトを見ているということです。1つ目のオブジェクトは分析レイヤーと呼ばれ、すべての計算を担います。分析レイヤーの操作はコンテキストメニューを使って行います。例えば、三角形をクリックして選択するなどです。もう1つのオブジェクトはレポートレイヤーと呼ばれ、分析レイヤーの結果を整理して表示します。
レポートレイヤーと通信したいとします。そのためには、メッセージを送信できるオブジェクト参照を使用します。このレポートレイヤーは分岐したツリー構造になっており、最初に参照するオブジェクトはこの表示ツリーのルートです。各分岐のノードはJMPの表示ボックスです。ここで問題となるのは、メッセージを送信したい表示ボックスをどのように特定または識別するかということです。これは添え字を使って行います。添え字は、元のレポートレイヤー参照に続く角括弧で囲みます。表示ボックスが深くネストされている場合は、複数の添え字を使用する必要がある場合があります。添え字は、連続した添え字でも、異なるボックスのリストを含む単一の添え字でも構いません。
添え字は複数の形式を取ることができます。絶対値、相対値、条件付きなどです。これを説明するために、まずは非常に簡単な例から始めましょう。大きなRESTデータテーブルを開きます。データテーブルに「by variant」メッセージを送信し、体重と身長の分析を開始します。参照を変数オブジェクトに保存したので、メッセージを送信できます。例えば、分析を有効にするために「fit line」というメッセージに数字の1を付与して送信すると、結果である赤い最小二乗近似線が表示されます。
しかし、プロットが表示されているボックスを選択したいので、レポートメッセージを使って解析レイヤーにその参照を問い合わせる必要があります。それを保存します。これで、その参照に添字を付けることができます。今回の場合は、フレームボックス1が適切な添字です。これについては後で説明します。そして、Selectというメッセージを送信します。これが添字の基本的な使い方です。
まず、絶対添字についてお話しましょう。この場合、インデックスを使って、表示ボックスの分岐構造を辿る際に、どの分岐を選択するかを指定します。例えば、適合の概要のアウトラインにある数字の列を選択したいとします。ルート、つまり指定された参照から始めて、分岐を辿っていきます。ルートから2番目の分岐、次に1番目の分岐、さらに1番目の分岐…と辿っていきます。最後に、selectメソッドを送信します。
ご覧の通り、これはうまく動作するはずです。絶対スクリプトは有効かつ効果的ですが、指定が非常に難しく、読みにくいという欠点があります。また、制約も存在します。つまり、様々な状況、開いているファイル、特定の操作を実行する順序、そしてJMP自体の更新などによって、簡単に動作しなくなるということです。お勧めしません。
相対形式の方が指定しやすく、読みやすいです。この場合、同じ数字の列を取得するには、「レポート」から始めて、下付き文字を次のように指定します。アウトラインボックス番号3、テーブルボックス番号1、数値列ボックス番号1を指定します。これを読んでいると、何をしているのかほぼ想像できるでしょう。結果は同じですが、こちらの方がより分かりやすいです。
3つ目の方法は、XPathクエリ言語を使用することです。この場合、レポートにXPathメッセージを送信します。このメッセージは1つの引数を受け取ります。引数とは、必要な情報を取得するための検索文字列を構成する文字列です。結果は最初の2つの方法と同じですが、最も脆弱ではありません。さらに、最も強力で柔軟性に優れています。すべての一致項目のリストを返し、このクエリ言語の多くの関数と条件付きロジックでサポートされています。
このスライドは、二変量ウィンドウのXMLファイルの冒頭部分を示しています。これは拡張マークアップ言語です。ここでは詳しく説明しませんが、これはJMPウィンドウを表現する方法であり、XPathクエリ言語はこの形式に基づいています。
JMPの表示ツリーやJMPのあらゆるウィンドウは、XMLで表現できます。XMLとは、階層的なデータや属性にタグを付けて保存するための言語です。JMPはこの言語のバージョン1を実装しており、この言語の詳細とその他のオンラインリソースを紹介する別冊の資料をご用意しています。
ここで、基本的な構文ルールをいくつか説明して、その概要を説明し、その後 Tanya にバトンタッチして、実際の使用例をいくつかお見せしてもらいます。
XPathには絶対パス形式もあります。これは、1つのスラッシュに続けて検索対象のノード名を記述することで示されます。さらにスラッシュを続けることで、連続するノードを表示します。ただし、JMPのウィンドウは動的であるため、JMPの表示ツリーでは、この方法は一般的に最適な方法とは言えません。
より良い方法は相対パスです。この場合、最初のノードを識別するために2つのスラッシュを使用します。そのノードは表示ツリー内のどこにでも出現でき、その後にさらにノードが続き、最終的に目的のターゲットを検索します。ノードは隣接している必要はなく、連続した枝である必要もありません。
3行目には簡単な例があります。検索文字列は、アウトラインボックスを探すための相対パスです。アウトラインボックス内のすべてのノードのリストが返されるので、非常に強力です。一方、述語(この場合は角括弧内のもの)を使って、より具体的な検索を行うこともできます。述語については後ほど詳しく説明しますが、これにより、すべてのアウトラインボックスではなく、タイトルと適合の概要を持つアウトラインボックスだけを検索対象とすることができます。
同様に、ワイルドカードも使用できます。ワイルドカードを使用すると、検索の詳細の一部を指定できますが、すべてではありません。タイトルに「summary」という単語を含むアウトラインボックスを検索したいとします。タイトルは「summary」でも、「summary of fit」のようなタイトルでも構いません。すべての一致が検索されます。また、これを使って次のレベルのすべてのノードを一致させることもできます。Outlinebox/* は、すべてのアウトラインボックス内のすべての表示ボックスを返します。
同様に、ノードだけでなく属性も検索できます。この場合、すべてのアウトラインボックスのすべての属性を検索します。@は属性記号で、アスタリスクはそれらのいずれかを表します。
述語についてもう少し詳しく説明しましょう。述語は角括弧で示されます。この場合、適合度のサマリー値を持つアウトラインボックスを検索しています。しかし、他にもできることはあります。2行目では同じ検索が行われていますが、一番最後にある数値列ボックスをすべて検索するのではなく、最後のボックスを検索します。このような情報を指定できます。例えば3行目では、最初の3つのアウトラインボックスを検索します。位置関数を使用しており、その値は一致する値よりも小さくなければなりません。ノードに関する情報だけでなく、そのノードの属性に関する情報も検索できます。幅が10より大きいテキスト編集ボックスをすべて検索することもできます。このような機能も利用できます。
検索しているときに、表示ボックスへの参照を取得してメッセージを送信したい場合があります。また、そのノードの値や属性を取得したい場合もあります。例を挙げましょう。すべてのアクセスボックスと、それぞれのテキスト編集ボックスを検索します。表示ボックスへの参照を返すのではなく、値やボックス内の現在のテキストなどを取得します。最後の行では、ウィンドウ内のすべてのアウトラインボックスの幅を取得したいと考えています。
最後に、XPathには軸という概念があることについてお話ししたいと思います。軸とは、先ほど述べたように、分岐、つまりあるノードから次のノードへ移動すること、そしてその途中で何を見つけるか、前方、後方、あるいは横方向を見ること、といった点において同じです。最初の例では、すべての軸ボックスを検索します。そして、特定のノードタイプを指定する代わりに、2つのピリオドでそれらの軸ボックスの親を検索したいことを示しています。
2行目も同様です。ヘッダーに平方和を持つ数値列ボックスのヘッダーを探しており、その親ノードを取得したいと考えています。これが実際の数値列ボックスです。関係性については明示的な宣言を使用できます。3行目の例では、最初の画像ボックスを参照しており、テキスト編集ボックスの子ノードを探しています。
逆の方法もあります。これはこのスライドの2番目の例と似ています。T-Ratioの数値列ボックスのヘッダーを探していて、その数値列ボックスタイプの表示ボックスの親を見つけたいのです。非常に強力で柔軟性の高い検索が可能です。多くの場合、単純な検索文字列で十分ですが、必要に応じて述語や、先ほど説明した他の構文ツールを使用することもできます。
JMPには役立つ機能がいくつかあります。ヘルプメニューを開いてスクリプトインデックスを検索すると、ブラウザの表示ボックスの表示形式が変更され、利用可能なすべての表示ボックスと、それらに関連付けられたすべてのプロトコルが表示され、検索も可能です。
また、アウトラインボックスの前にある灰色の三角形を右クリックするとメニューが表示され、そこから「表示ツリーを表示」または「プロパティを表示」を選択できます。これらはインタラクティブなツールで、表示ツリーの内容や値、属性を確認するのに役立ちます。非常に便利です。
また、拡張ログは検索結果を確認し、さらに修正が必要かどうかを確認するのに最適な方法です。JSLメッセージ「Get XML」があります。基盤となるXML表現を確認する必要がある場合があり、非常に役立ちます。また、JSL関数「Get Display Path」は、対象の表示ボックスを参照するための適切な添え字形式またはXMLパス形式を示します。
私からは以上です。それでは、Tanyaにライブデモンストレーションをお願いしたいと思います。
マーク、ありがとう。この最初のケーススタディでは、JSLを使ってレポートで見つかった値を取得したいと思います。まず最初に、これらの値を保持している要素を特定する必要があります。その方法の一つは、「プロパティを表示」を使うことです。
「プロパティを表示」をクリックすると、平均値が数値列ボックスに含まれていることがわかります。このパネルには、マークが先ほど説明したネストされた、あるいは分岐したツリー構造が表示されています。この数値列ボックスはテーブルボックスの一部であり、テーブルボックスはアウトラインボックスの一部です。
ここには、このボックスのパスアウトラインノードがあります。これは、この数値列ボックス「mean」への参照を取得するためのJSLです。デフォルトのモードは添え字方式です。これをXPathに変更すると、JMPは「mean」という数値列ボックスへの参照を取得するためのXPathコードを表示します。
どの要素に情報が格納されているかがわかったら、その要素にどのようなコマンドを送信できるかを考えます。その方法の一つは、スクリプトインデックスを使うことです。数値列ボックスを検索すると、送信できる様々なgetメッセージがあることがわかります。ここでは、get as a matrixを使用します。
この情報を取得するには、いくつかの方法があります。最初の方法は、レポートに送信することです。RPTは、先ほどマークが説明したレポートレイヤーです。レポート内で最初の数値列ボックスを探し、その値をマトリックスとして取得します。これらの値はログの下部に記載されています。レポートを確認すると、同じ値であることがわかります。
次に、XPathコマンドを使って同じ情報を取得します。今回は、アウトラインボックスのタイトル「測定の変動サマリー」を探します。ヘッダーの平均値が入った数値列ボックスを探し、それを行列として取得します。
最後に、相対的な添え字を使用します。レポート内で、測定の変動サマリーと平均と呼ばれる数値列ボックスを探し、これを行列として取得します。
ここで紹介した3つの方法はすべて同じ結果を得ていますが、最初の方法は推奨しません。堅牢性に欠けるからです。将来、JMPがレポートを変更し、数値列ボックスを追加した場合、このコードを実行しても期待どおりの結果は得られなくなります。
最後の2つの例は非常に堅牢な変更です。最後に示した相対的な例は、XPathの例よりも短くなっています。これは通常、レポートから1つの要素だけを抽出する場合に当てはまります。XPathが真価を発揮するのは、一度に複数の要素を抽出する場合や、先ほどマークが述べたようにワイルドカードや述語を使った複雑な処理を実行する場合です。
もう少し複雑な例を見てみましょう。このケーススタディでは、両方の回答の制限要約情報を抽出したいと考えています。回答は2つあり、両方の情報を取得したいのです。これは、2つの列で相対添字を使用することで実現できます。
レポートレイヤーでは、その下に表示される最初のテーブルボックスで重量制限の概要を検索し、その情報を取得できます。次に、最初のテーブルボックスで重量制限の概要を検索し、その情報を取得する2番目のコマンドを実行します。
あるいは、Xグラフコマンドを1つだけ使うこともできます。レポートレイヤーで、「管理図ビルダー」というアウトラインボックスを探します。上の図に表示されています。管理図ビルダーの下に表示されるすべてのテーブルボックスを探して、その情報を取得できます。
このコードを書くと、予想以上に多くの情報がログに出力されます。ここに表示されているのは、レポートに表示されるテーブルボックスと、非表示のテーブルボックスです。このレポートには他にもテーブルボックスが含まれていますが、追加された制限やSigmaレポートなど、これらの情報はまだレポートレイヤーに追加されていません。XPathステートメントに情報を追加することで、表示を向上できます。
これらのテーブルボックスすべてについて、テーブルボックス自体とその祖先を調べ、それらが表示されているかどうかを確認したいと考えています。このコードでは、可視性が false かどうかを確認していますが、ここに not ステートメントも含まれています。つまり、レポートに表示されているテーブルボックスです。これを実行すると、上記の 2 つのステートメントで取得したのと同じ情報を取得できます。XPath により、この情報を 2 つのステートメントではなく 1 つのステートメントで取得できるようになりました。
次のケーススタディでは、予測プロファイラーを作成し、望ましさを最大化しています。このレポートに含まれる赤色のY値と赤色のX値を取得したいと考えています。これらはどちらも軸の値であり、どちらも赤色であるため、同じ要素に格納されていると思われるかもしれませんが、実際にはそうではありません。
「プロパティの表示」ウィンドウに戻ると、これを確認できます。適切なものをクリックすると、Y値がテキストボックス、X値が数値編集ボックスになっていることがわかります。まず、テキストボックスを操作してみましょう。XPathを使って予測プロファイラーを検索し、次に表示されているテキストボックスを検索します。ここでも、レポートには表示されないテキストボックスがいくつかあるため、表示に関するコードを追加する必要がありました。これらのテキストボックスは表示したくないからです。
このコードを実行すると、赤色の値だけでなく、信頼区間の青色の値も取得されていることがわかります。これは、青色の値もテキストボックスとして保存されているためです。各要素を循環的に処理するforループを追加し、赤色の値だけを3つごとに取得し、この情報を行列に格納します。
Y値は赤で表示されていますが、X値も赤で表示されています。これらは数値編集ボックスに格納されています。XPath文を使って、数値編集ボックス内の予測プロファイラーを検索し、それらの値を行列として取得します。これらの値は、下のログに表示されています。
次のケーススタディでは、最初のフレームボックス、つまりこの位置チャート(平均直径)に含まれるすべてのラインのY値をすべて取得したいと考えています。「プロパティの表示」を見ると、このフレームボックスレイヤーには実際にはアクセスできないことがわかります。ここをクリックするとフレームボックスが表示されますが、フレームボックスの中身は見えません。これらの値がフレームボックスにどのように保存されているかを知る必要があります。この情報を取得するもう1つの方法は、「ツリー構造の表示」を使用することです。
「ツリー構造を表示」では、先ほどマークが説明した分岐構造も確認できます。このフレームボックス内には、様々なセグメントがあります。私が注目しているのは、ここに表示されている線分です。XPathステートメントを使って、最初のフレームボックスからすべての線分を取得できます。
以前は、すべてのXPathステートメントにアウトラインボックスノードがありました。今回はアウトラインボックスノードがありません。管理図ビルダーでは、アウトラインボックスノードは実際には必要ありません。管理図ビルダー内のすべてのグラフは、複数のレスポンスがある場合でも、この管理図ビルダーのアウトラインの下に表示されます。したがって、この処理ではアウトラインボックスノードは実際には必要ありません。
これを実行すると、7つの要素があることがわかります。これらの要素からY値を取得するために連想配列を使用できます。実行後、追加された平均値のY値は4.2、追加された下限値のY値は4.1、などとなります。
次のケーススタディでは、3つの異なるグラフを用意します。それぞれのグラフのY軸の最小値と最大値を同じにし、同じ参照線を追加します。まず、軸ボックスのハンドルを取得する必要があります。XPathを使用して、フィットグループのアウトラインノードを検索します。次に、表示されているすべての軸ボックスを検索します。
6つの異なる軸ボックスがあるのがわかります。グラフは3つあり、それぞれX軸とY軸なので、合計6つです。forループを使って、それぞれの値を循環的に処理します。Y軸のみ、最小値と最大値を設定し、参照線を追加します。これで、3つのグラフそれぞれに参照線が追加され、最小値と最大値が同じ値に設定されました。
次の例では、このSigma Capability Summary Report全体を短縮します。PPまでの表示のみを表示し、CPMや期待値、実測値は表示しません。これはXPathで実現できます。レポートレイヤーにアウトラインボックスコマンドを送信し、Sigma Capability Summary Report全体を検索します。
レポートの該当レベルへの参照を取得したら、XPathを使って「期待値」、「実測値」、「等しいCPM」で始まるヘッダーボックスを選択します。これらを選択したら、表示/非表示コマンドを送信します。すると、レポートからこれらの値が消えていることがわかります。レポートから項目を削除しないことが重要です。レポートから項目を削除すると、予期せぬ結果が生じる可能性があります。項目を削除するのではなく、レポート内の項目を折りたたむか非表示にすることをお勧めします。
最後にもう一つ例を挙げましょう。このケーススタディでは、「Manage Limits」プラットフォームを新しいウィンドウ内に配置しており、このヘルプボタンを削除したいと考えています。JSLスクリプトを作成する際、結果を他の人と共有したいという理由で、このような操作を行うことがよくあります。そのため、スクリプトが自分のコンピュータでも他の人のコンピュータでも同じように動作することを確認する必要があります。
WindowsとMacintoshでは、ボタンの位置が異なることがよくあります。レポート内の位置に基づいてボタンを探すことは避けるべきです。位置ではなく、名前に基づいてボタンを探す必要があります。ここではウィンドウハンドラーのコードについては詳しく説明しません。ここで注目していただきたいのは、このXPathステートメントです。「ヘルプ」というタイトルのボタンボックスを探し、非表示にしています。すると、ヘルプボタンがここに表示されなくなっているのがわかるでしょう。繰り返しますが、単にクリックしただけです。予期せぬ結果を招くのを避けるため、レポートから削除したくありません。
レポートから値を取得する3つの方法を紹介しました。絶対添字は変更に対して堅牢ではないため、あまり良い方法ではありません。XPathメソッドと相対添字はかなり堅牢です。レポートから単一の値を取得するだけであれば、相対添字の方がコードが短くシンプルになるでしょう。XPathコードは、一度に複数の情報を収集する場合や、ワイルドカードなどを使って複雑な処理を行いたい場合に便利です。
この情報が役に立ち、戻ってスクリプトを書く準備ができたら幸いです。