If()関数は、条件(condition)が真(0でない非欠測値)であると評価された場合に、結果(result)のステートメントを戻します。真でない場合には、先に進み、次に条件が真と評価されたときの結果を戻します。
構文は次のとおりです。
If ( condition, result1, result2 );
たとえば、次のスクリプトは年齢が12より小さい場合、"若い"を戻します。そうでない場合は、"気持ちが若い"を戻します。
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt << New Column( "年齢層", "性格" );
For Each Row(
:年齢層 = If( :年齢 <= 12,
"若い",
"気持ちが若い"
)
);
複数の条件と結果をつなげることもできます。構文は次のとおりです。
If( condition1, result1,
condition2, result2,
...,
resultElse );
この例では、条件1(condition1)が真でない場合、関数は真の条件を見つけるまで評価を続けます。そして、真である条件の結果を戻します。
すべての条件が偽のときは、最後の結果を戻します。値がない場合は欠測値を戻します。そのため、式の最後にデフォルトの結果を含めておくことが大切です。次に、「Big Class.jmp」の性別の略称をコード変更する例を見てみましょう。
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
For Each Row( 性別 =
If(
性別 == "F", "女性",
性別 == "M", "男性",
"不明" );
);
このスクリプトは次のように機能します。
For Each Row( 性別 = |
テーブルの各行で「性別」の列の値を変更するよう指定する。 |
If( |
If()ループを開始する。 |
性別 == "F", "女性", |
「性別」の値が「F」であれば、その値を「女性」に変更する。 |
性別 == "M", "男性", |
「性別」の値が「M」であれば、その値を「男性」に変更する。 |
"不明" ); |
どちらの条件も真でない場合は値を「不明」に変更する。この部分が指定されず、「性別」が欠測値になっていた場合は、欠測値を戻します。 |
); |
ループを終了する。 |
結果の式にアクションや割り当てを挿入することもできます。次のスクリプトは、最初の条件(y < 20)が偽なので、xに20を割り当てます。
y = 25;
z = If( y < 20, x = y, x = 20 );
注: 等しいことを調べる場合には、=ではなく、==を使います。If関数にname=valueといった引数が付いている場合は、値を調べるのではなく割り当てます。
何十ものIf()ステートメントを含むスクリプトを実行することはメモリの問題を起こす場合があります。If()の入れ子をあまり増やさないようにしてください。たとえば次のように、スクリプトに100個のIf()ステートメントが入れ子になっているとします。
If( val, If( val, If( val, If( val, If( val,
If( val, If( val, If( val, If( val, If( val,
...
) ) ) ) ) ) ) ) ) );
このスクリプトは以下のように書き直せます。
If( val, val1, If(val, val2, If( val, val3,
If( val, val4, If( val, val5, If( val, val6, ...) ) ) ) ) );
また呼び出しの最大の深さを設定するということもできます。Maximum Call Depth環境設定で、JSLに組み込まれる関数、ユーザー定義の関数、またはRecurse()関数の呼び出しで作られる呼び出しの最大の深さ(あるいはスタックサイズ)のデフォルトを設定することができます。呼び出しの最大の深さのデフォルトは256です。
JMPでは、JSL関数呼び出しのための物理的な実行スタックメモリに制限を設けています。このサイズは、デフォルトで2MBです。呼び出しの最大の深さを増やすと、物理的な実行スタックがオーバーフローを起こす可能性があるので、JSLスクリプトがうまく動作する最良の値を見つけるまで、この環境設定を少量ずつ増加させてください。
Preferences[1] << Set( Maximum JMP call depth( 64 ) );