私の職業生活を考えるとき、私はJMPに比較的新しい人です。実際、私のJMPとJSL(JMP Scripting Language)の経験は、私がここ4年ほど前にJMP Life Sciencesグループの開発者になった日から始まりました。 それとは対照的に、私は数学の学部生だったときからSASを使っていて、20年以上の経験があります。 2つの言語の間には多くの違いがありますが、私の仕事で私が一番楽しんでいることの1つは、この非常に大きくて豊富なツールセットを使ってクールな新機能を開発することです JMPクリニカル 。
両方にアクセスできても JMP そして SAS JSLを使用してSASで機能を複製する方法を疑問に思うことがあります。このブログ記事の主題は、SASデータステップの振る舞いを複製して、グループ内の最初と最後のレコードを選択する方法です。 SASでは、これは最初にデータをソートし、データステップ内で特別なキーワードを使用して実行されます。 たとえば、Big ClassデータテーブルをSASでフォーマットし、最初の男の子と女の子をアルファベット順に選択したい場合は、以下のプログラムでこれを達成できます。
proc sort data = bigclass;
性別による。
走る。
最初にデータ。
ビッグクラスを設定します。
性別による。
first.sexの場合
走る。
最後の男の子と女の子をアルファベット順に選ぶには、 last.sexの場合 。 追加のグループ内で最初と最後を選択したい場合も、同様の論理が適用されます。 たとえば、性別内の各名前に対して最短の人を選びたいとします。次のようにします。
proc sort data = bigclass;
性別の身長による。
走る。
最初にデータ。
ビッグクラスを設定します。
性別の身長による。
first.nameの場合
走る。
私の同僚ブレイディブレイディ Col Min()およびCol Max()を使用してJSL内でこれを解決するのに十分なほど親切でした。 図1にサンプルデータセットを示します。元のデータには、レター(AからJ)とレター2(AからD)のみが含まれていました。 データテーブルはこれら2つの変数によってソートされます。下記のように、First.LetterはLetterの各文字の最初のインスタンスに対して1に等しくなります(そうでなければ0)。Last.Letterは、Letterの各文字の最後のインスタンスに対して1です(それ以外の場合は0)。これらの変数の公式は次のとおりです。
First.Letter = If(Row()== Col Minimum(Row()、:Letter)、
1、
0
)
Last.Letter = If(Row()== Col Maximum(Row()、:Letter)、
1、
0
)
これらの式を解釈するために、Col M ** imum()関数は次のものを使用しています。Let by byグループとして、Letterの各値内の最小または最大行番号を取得します。現在の行番号が文字固有の最小行番号と等しい場合、If()関数はFirst.Letter = 1を設定します。 :Letterの特定の値が単一行のみの場合、そのレコードは最初と最後の両方と見なされます。最初の一文字 = 1かつラストレター= 1

図1。データテーブルFirstLast
上記のSASのコードと同様に、これは複数の変数によって拡張できます。 Letter2の各文字の最初のインスタンスを選択したいとします。内に手紙、私は単に関数に追加のbyvarを追加します。
First.Letter2 = If(Row()== Col Minimum(Row()、:Letter、:Letter2)、
1、
0
)
Last.Letter2 = If(Row()== Col Maximum(Row()、:Letter、:Letter2)、
1、
0
)
これらの関数には、重複が発生するグループごとに簡単にサブセット化できるという点で便利な機能があります。 行を選択する場所最初の一文字 = 0または最後の手紙 = 0は、すべての行を選択します。ここで、文字が繰り返されます。Big Classのコンテキストでは、次の関数を使用します。Heightでは、特定の高さを繰り返すことができるサブテーブルを作成できます。
SASでは、特別なfirst.XX last.XX変数を作成するためにソートが必要です。 上記のデータテーブルはソートされていますが、これは上記のJSLコードが機能するための要件ではありません。
Brady Bradyに助けてくれてありがとう!