2 つの列で作成されたグループの行をループする方法こんにちは、みんな、
非常に単純な質問がありますが、フォーラムから正確な答えを見つけることができません。 これが私のサンプルデータテーブルです。

基本的に4つの列があり、「グループ1」と「グループ2」から生成される各組み合わせアイテムをループする必要がありますが、「アイテム」#が異なる場合に限り、「パス」列のすべてのファイルパスを開きます。 たとえば、最初の 2 行では、組み合わせが「aA」ですが、項目も異なるため、スクリプトはファイル パス 1 と 2 の両方を開く必要があります。
データのブレンディングとクリーンアップRe: 2 つの列で作成されたグループの行をループする方法はい、それは実際にとても役に立ちました。 file_list 変数は、ファイルを開くために厳密に必要なわけではないため、混乱を招くものでした (ただし、後ですべてのファイルを再度閉じる (?) 場合やその他の操作の場合に便利であると私は考えています)。 また、反復ごとに異なるファイル パスに割り当てられる「file_path」変数について理解するのに時間がかかったということと、それが何と呼ばれるかは問題ではないことを認めなければなりません。 (私の頭の中では、filepaths_to_open リストからファイル パスを 1 つずつ選択し、ユーザーがそれに対して「何か」できるようにする手段だと今は解釈しています。)
ありがとう! 毎週少しずつ知識が増えていくことは、まったくないよりはマシです。
追伸: 以下は、あなたの説明を理解した上でしか書くことができませんでした。 繰り返しますが、非常に便利です。
Names Default To Here( 1 );
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
For Each( {file_path}, filepaths_to_open, Open( file_path ) );
Re: 2 つの列で作成されたグループの行をループする方法これらは、デモ スクリプトを書くのが最も理解しやすいと思います (IDX を追加するために For Each を少し変更しました。それがどのように機能するかをもう少し理解しやすくなるかもしれません)
Names Default To Here(1);
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
show(filepaths_to_open);
file_list = {};
show(file_list);
For Each({file_path, idx}, filepaths_to_open,
show(idx, file_path);
Insert Into(file_list, Open(file_path));
show(file_list);
);
- file_list を使用して、開かれているデータテーブルへの参照を収集します (ファイルパスは既に filepaths_to_open にあるため必要ありませんが、参照はありません)。
- Open(file_path) は開かれたファイルへの参照を返し、Insert Into はその参照を file_list に追加します。
- {filepath} の由来機能ごとに使用すべきです。 基本的に、filepaths_to_open をループし、file_path 変数内の各要素を (1 つずつ) 返します。
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
file_list = {};
idx = 1;
file_path = "$SAMPLE_DATA/Big Class.jmp";
file_list = {DataTable("Big Class")};
idx = 2;
file_path = "$SAMPLE_DATA/Probe.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe")};
idx = 3;
file_path = "$SAMPLE_DATA/Iris.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe"), DataTable("Iris")};
いくつかの質問に答えていただければ幸いです。
Re: 2 つの列で作成されたグループの行をループする方法@jthi , コードの最後の部分、つまり理解できない点に関していくつか質問したいのですが。
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);
file_list = {};
これは空のリストです。 ループは Insert Into(file_list, Open(file_path)) を介してこれを埋めます。 filepaths_to_open に既に含まれているリストを使用できないのはなぜでしょうか? また、Open(file_path) がリストに何かを挿入する方法がわかりません。 これはファイルを開くだけの機能ではないでしょうか? いったいどうやってリストに貢献できるのでしょうか?
{file_path}これも、分かりません。 これは実際のファイルパスの単なるプレースホルダーですか?
これらのことを説明した参考文献をお持ちですか? 先ほどは誠にありがとうございました。
Re: 2 つの列で作成されたグループの行をループする方法ValidFile チェックの構築方法に応じて、ValidFile の計算と、場合によっては行の選択を変更する必要があります。
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
If(Col Sum(1, :g1, :g2, :i) == 1 & Col Number(:i, :g1, :g2) > 1,
1
,
0
);
));Re: 2 つの列で作成されたグループの行をループする方法@jthi 、いつものようにきちんとしています。 良い勉強になりました、ありがとう。
Re: 2 つの列で作成されたグループの行をループする方法別の列「Unique」を作成して、なんとか見つけました。
new_col = dt << New Column("Unique", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2);
));
rows_to_open = dt << Get Rows Where(:ValidFile == 1 & :Unique != 1);
Re: 2 つの列で作成されたグループの行をループする方法ありがとうございます! 最後の質問ですが、列 g1、g2、および i に有効なファイルの組み合わせが 1 つしかない場合、式をさらに変更して無視するにはどうすればよいですか?

Re: 2 つの列で作成されたグループの行をループする方法メッセージを編集して古い変数の名前を変更しました。 文字列を合計しているのではなく、グループ化 () から文字列を使用しています。 1 を使用するので、グループ内の行ごとに 1 ずつ増加するものになります。 これらの関数を使用してさまざまなタイプの数式を作成すると、その動作を理解しやすくなる場合があります。スクリプト索引にはいくつかの例も掲載されています。
Col Sum(名前,)
Re: 2 つの列で作成されたグループの行をループする方法こんにちは。
3つの異なるオプションを含む素晴らしい回答をありがとうございます。 補足の 1 つは、コードを実行するには rows_to_open1 変数から「1」を削除する必要があることです。 今後の参考のためにこのタイプミスを修正していただければ幸いです。
それ以外に、あなたの回答に関連する質問があります。 Col Sum、Col Cumulative Sum、Col Max(Col Sum?) のそれぞれの値「1」の目的は何ですか? そして、なぜ列 g1 と g2 の文字値を合計できるのかわかりません。
Re: 2 つの列で作成されたグループの行をループする方法こんにちは、レッセルさん
あなたの解決策を試してみましたが、確かに印刷されましたあなたが述べたように、「ファイルパス6」を2回。 私が見たもう1つの問題は、同じ行を2つ持つために行5の項目値を意図的に5から7に変更したときに、最後の行(「ファイルパス6」)が印刷されてしまうことです。 それを回避する方法はありますか? jthi の代替 for ループにも同じ問題があることがわかります。


Re: 2 つの列で作成されたグループの行をループする方法@レッセル
ループ構造を再考するのが最も簡単だと思いますが、二重出力を行わずに現在のループ構造も希望どおりに機能させることもできます。出力されたもののリストを保持するか、それを防ぐために何らかの追加ロジックを考え出す必要があります。起こることから。 以下のアイデアが機能するはずだと思います。
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j < N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print(dtTemp:path[j]);
If(j + 1 == N Rows( dtTemp ),
Print(dtTemp:path[j + 1]);
)
)
);
Close( dtTemp, no save );
);
たとえば、ここでは最後の値をループするのではなく、次の値が最後かどうかを確認し、最後である場合はそれも出力します(現在の行を出力した場合)。
Re: 2 つの列で作成されたグループの行をループする方法問題を正しく理解しているかどうかはわかりませんが、以下に Col Sum/Col Cumulative Sum と Col Max(ColSum()) を使用する 3 つの異なるオプションを示します。
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(8),
Compress File When Saved(1),
New Column("g1", Character, "Nominal", Set Values({"a", "a", "a", "a", "a", "c", "c", "c"})),
New Column("g2", Character, "Nominal", Set Values({"A", "A", "B", "B", "B", "A", "A", "A"})),
New Column("i", Numeric, "Continuous", Format("Best", 12), Set Values([1, 3, 2, 4, 4, 5, 7, 9])),
New Column("p",
Character,
"Nominal",
Set Values({"filepath1", "filepath2", "filepath3", "filepath4", "filepath4.1", "filepath5", "filepath6", "filepath7"})
)
);
// depending how we handle duplicated g1+g2+i we would use different formulas
// if we won't open any
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2, :i);
));
/*
// if we open the first one
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Cumulative Sum(1, :g1, :g2, :i);
));
*/
/*
// if we don't open g1+g2 at all
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Max(Col Sum(1, :g1, :g2, :i), :g1, :g2)
));
*/
rows_to_open = dt << Get Rows Where(:ValidFile == 1);
filepaths_to_open = dt[rows_to_open, "p"];
show(filepaths_to_open);
// dt << Delete Column(new_col);
// To open files loop over filepaths_to_open
stop();
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);

ValidFile が 1 である行を選択し、それらのファイルを開くというアイデアです。 この画像は、3 つの異なる式の計算を示しています。
編集:
古いリファレンスを修正開く行数1に開く行数
Re: 2 つの列で作成されたグループの行をループする方法NChooseK Matrix() を調べて、それが適切かどうかを確認してください。スクリプト索引では、次のように説明されています。 1 から n までの k 整数のすべての組み合わせを形成する nChooseK(n,k) 行と K 列の行列を作成します。
文字データ型で動作するように変更できるでしょうか?
Names Default To Here( 1 );
Print( NChooseK Matrix( 5, 3 ) );
__________________________
Prints:
[ 1 2 3,
1 2 4,
1 2 5,
1 3 4,
1 3 5,
1 4 5,
2 3 4,
2 3 5,
2 4 5,
3 4 5]
Re: 2 つの列で作成されたグループの行をループする方法こんにちは、以下は少なくともあなたがやりたいことを始めます。 「」を変更するだけです。 Print( dtTemp:path[j], dtTemp:path[j + 1] )"ファイルを開く機能を備えた部分です。
しかし、残念なことに、私が書いた方法では、このスクリプトは「ファイル パス 6」をログに 2 回出力するため、それに応じて変更すると、「ファイル パス 6」も 2 回開きます。 それを回避する方法はあると確信していますが(ファイルパスがすでに開かれているかどうかを確認するなど)、ここでは遅くなっています。 とにかく、残りの方法も見つけたら、お知らせします。 フィードバックは大歓迎です!
dt = New Table( "today's challenge",
Add Rows( 7 ),
New Column( "group1",
Character,
"Nominal",
Set Values( {"a", "a", "a", "a", "c", "c", "c"} )
),
New Column( "group2",
Character,
"Nominal",
Set Values( {"A", "A", "B", "B", "A", "A", "A"} ),
Set Display Width( 70 )
),
New Column( "item",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [1, 3, 2, 4, 5, 7, 9] )
),
New Column( "path",
Character,
"Nominal",
Set Selected,
Set Values(
{"file path 1", "file path 2", "file path 3", "file path 4",
"file path 5", "file path 6", "file path 7"}
)
)
);
dt << New Column( "PairedGroup", formula( :group1 || :group2 ) );
PairedGroupList = Associative Array( dt:PairedGroup ) << Get Keys;
dt << Clear Column Selection;
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j <= N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print( dtTemp:path[j], dtTemp:path[j + 1] )
)
);
Close( dtTemp, no save );
);