こんにちは。私は、どの言語でもスクリプト作成の初心者です。現在、簡単な練習課題だと思っていたものを試行錯誤しています。JMP18 を使用しています。目標は、時間の経過とともに増え続けるデータセットに対して行う定型操作を自動化することです。定型操作は、まず時間スケールを決定し、次に大規模なデータセットのその時間スケールでのデータの変化を表示することです。私がこれに取り組んでいる基本的な方法は、すべての初期データを入力する新しい列を作成し、より多くの列で数式を使用して差異を取得することです。もっと良い提案があれば、ぜひ教えてください。現在の状況は次のとおりです。
本質的には、私は一連のデータを持っており、次のことを達成したいと考えています。
1) 日付と時刻の列を 1 つの列にまとめて、最小値を見つけ、それを使用して開始日を作成したいと考えています。その後、時間を減算して、データ間の時間の違いを確認できます。これは、formula() 関数を使用すると非常に簡単です。ここではすべてがうまく機能します。
2) いくつかのデータ列に似たようなことをしたいのですが、以前行ったように初期値を見つけることができません。初期データは、3 番目の列 (以下のコードでは Unique_Fruit と呼ばれます) のすべての一意のアイテムに対して以前行った操作で見つかった最小時間によって決まります。このフォーラムのために、各 unique_fruit に対して、その果物のデータの初期値を含む列を作成し、実際のデータ列からの変更をすばやく計算できるようにしたいと思います。
私の現在の JSL スクリプトは以下のとおりです。何をすればよいかまだわかっていないダミー コード式があります。これは、If 関数を使用して、時間が互いに等しいことを見つけ、それらのセルにのみ値を設定する手順です。当初の考えでは、for ループを使用して式を反復処理しようとしましたが、うまくいかないようでした。
DataTable = Current Data Table();
New Column( "Date Number Format", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Date Number Format[i] = Num( DataTable:Key_Date[i] );
);
New Column( "Time Number Format", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Time Number Format[i] = Num( DataTable:Key_Time[i] );
);
New Column( "Current_Time", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Current_Time[i] = DataTable:Date Number Format[i] + DataTable:Time Number Format[i];
);
New Column( "Unique_Fruit", Character, "Nominal" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Unique_Fruit[i] = DataTable:Fruit[i] || "-" || DataTable:Type[i];
);
New Column( "Starting_Date_Number_Format", Numeric, "Continuous",
Formula( Col Minimum( :Current_Time, :Unique_Fruit ) )
);
New Column( "Minutes", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Minute", "fractional" ) )
);
New Column( "Days", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Day", "fractional" ) )
);
New Column( "Weeks", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Week", "fractional" ) )
);
New Column( "Months", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Month", "fractional" ) )
);
New Column( "Initial_Taste", Numeric, "Continuous",
Formula(
If( :Current_Time == :Starting_Date_Number_Format, :Key_Taste, . )
)
);
For( i = 1, i <= N Rows( DataTable ), i++,
If( DataTable:Current_Time[i] == DataTable:Starting_Date_Number_Format[i],
DataTable:Initial_Taste[i] = DataTable:Key_Taste[i];
);
);
New Column( "Delta_Taste", Numeric, "Continuous",
Formula( :Key_Taste - :Initial_Taste )
);
New Column( "%_Change_Taste", Numeric, "Continuous",
Formula( ( :Delta_Taste / :Initial_Taste ) * 100 + 100 )
);</CODE></P><BR /></LINGO-BODY><LINGO-LABS id="lingo-labs-844919" slang="en-US" mode="CREATE"><LINGO-LABEL>自動化とスクリプト</LINGO-LABEL></LINGO-LABS><LINGO-SUB id="lingo-sub-844929" slang="en-US" mode="CREATE">Re: スクリプトを書こうとしている初心者 / 数式関数内で反復処理するにはどうすればいいですか?</LINGO-SUB><LINGO-BODY id="lingo-body-844929" slang="en-US" mode="CREATE"><P>正解のデータセット+列の例を提供できますか?おそらく、次のようなものを使用して初期値を取得できますが、これは各カテゴリの最初の値を取得するため、比較を変更する必要があります。</P>
<BR />
<PRE><CODE class=" language-jsl">Col Cumulative Sum(If(Row() == Col Min(Row(), :age), :height, .), :age)
ここで、:age は unique_fruit、:height は値の列です。Lag() と変数も利用できます。
スクリプトをもう少し堅牢にするために、いくつか変更を加えることもできます。
- Names Default To Here(1); でスクリプトを開始します。
- データテーブルへの参照があるのでそれを使用します
- DataTable << 新しい列(...
- JMPにはDatatable()という関数があるので、DataTableをdtなどに変更することも検討します。
- データテーブルをループする場合は、特別な使用例であるため、ForではなくFor Each Rowを使用します。
- 数式を使用せずに JMP テーブルに新しい列を追加したい場合は、いくつかのオプションがあります。
- 新しい列 + 数式 + 数式の実行 + 数式の削除の組み合わせを使用する
- 新しい列を作成し、データテーブルをループします(現在行っているように)
- 次に、<< Apply Formula を使用するという少し厄介な方法がありますが、私はまずこれらを使用します (通常は最初の方法を使用します)
コミュニティへようこそ。
サンプルデータテーブルである Jarmo に同意します。
また、期待される結果の模擬例を示すこともお勧めします。
ご提案ありがとうございます。私はモック データセットを試みており、現在は手動で行っています。初期値を設定するには、各一意の項目を調べ、そのセルからデータを呼び出して列全体に入力し、計算の次の部分に進むことができます。スクリプトの残りの部分もご提案に従って更新してみますが、私にとっては主要な問題はまだ解決されていないと思います (または、まだ理解できていないのです)。
一般的に、正しい質問に答えるよりもモックアップデータを作成するのに時間がかかるため、解決されませんでした。初期値にはこのようなものを利用できるはずです。
Col Min(If(:Date Number Format == Col Min(:Date Number Format, :Unique_Fruit), :Key_Taste, .), :Unique_Fruit)
これはこれらを構築する唯一の方法ではありませんが、このような方法はかなり頻繁に機能します
ありがとうございます。念のため言っておきますが、私はあなたの最初の回答を責めようとしたのではなく、何度か繰り返して実装しようとしていたのですが、まだ何かが足りないと思いました。おそらくここで示した答えにたどり着いたでしょうから、そのまま続けるべきでしたが、先ほど言ったように、私はこうしたスクリプトの作成に不慣れなので、ゆっくりと進んでいます。
興味深いのですが、else に「.」があるのはなぜですか?
欠損値は、欠損値が無視されるため、Col Min に選択できるオプションが 1 つだけになるように「強制」するために存在します。
このタイプの数式は、理解を深めるために複数の部分に分割することができます(それでも非常に難解な場合があります)
//col1
Col Min(:Date Number Format, :Unique_Fruit)
//col2
:Date Number Format == :col1
//col3
If(:col2, :Key_Taste, .)
//col4
Col Min(:col3, :Unique_Fruit)

こんにちは、これをいじっているときに、追加の考えが浮かびました。これを投稿したときに最初に考えていたことに近いことをしたい場合、どうすればいいでしょうか? 私が現在行っているのは、リストを格納する変数を作成し、そのリストを反復処理して数式に値を入力するコードを作成しようとしているところです。変数に値を入力する代わりに、リスト値の 1 つに更新するのではなく、数式内に残ります。これは数式関数内で実行できるものなのでしょうか?
ここでの説明に感謝します。私は自分自身のためにこの小さなプロジェクトを続けながら、それを試してみて、どこまでできるかを見ています。
数式内で値のリストを取得したり、値のリストを収集したりできますが、値の更新方法に注意する必要があります (As Constant または If(Row() == 1,...) を使用すると役立ちます)。また、数式内のループは頻繁にトリガーされるため、避けたほうがよいでしょう。
Lag() を使うこともできますが、そのためにはデータをソートする必要があります (ソートしなくてもできますが、すぐに複雑になります)。ただし、通常は次のような考え方になります。
If(Row() == 1,
init_taste = :Key_Taste
);
If(:Unique_Fruit != Lag(:Unique_Fruit),
init_taste = :Key_Taste;
);
init_taste;
データは Date Number Format と Unique_Fruit で並べ替えたことに注意してください。