データをドロップダウンとして表示する最適な方法は、データ フィルターではありません。
こんにちは、みんな、
主キーと外部キーを使って結合した2つのデータテーブルを操作しており、そこには数千ものデータが含まれています。目標は、これらのテーブルの値をドロップダウン(現在はコンボボックスを使用)に表示し、選択内容に基づいてサブセットテーブルまたは転置テーブルを動的に生成することです。
Currently, I’m using ComboBox to populate unique values from the data tables, but performance is quite slow and especially with larger datasets. I’ve found that JMP’s built-in Data Filter is powerful but not very customizable for UI integration.
バックグラウンドでデータフィルターエンジンを活用し、カスタムUIドロップダウンに接続する方法はありますか?あるいは、JSLのドロップダウンとしてレスポンシブで動的なフィルタリングを実現する、より効率的な方法はありますか?
ご提案や例があれば、ぜひ教えてください!
前もって感謝します。
自動化とスクリプト基本的なデータ分析とモデリングRe: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。JMP19 の新しいフィルター ビューをご覧ください。
データ テーブル自体と、テーブルの右側にあるフィルター ビューを使用することもできます。

表示に満足したら、新しいテーブルとして開くだけです。
詳細については、次の講演をご覧ください: @Mandy_Chambersによる「開発者チュートリアル: データ テーブルの機能強化」 。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。JMPの旧バージョンからJMP 19に移行中です。そのため、このソリューションは旧バージョンでは機能しません。ドロップダウンで大量のデータをより速く表示する方法について何かアイデアはありますか?データフィルターは高速ですが、UIのカスタマイズ性は低いです。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。どの部分が遅いですか?コンボボックスの作成ですか?値の検索ですか?サブセットの作成ですか?
いくつか最適化できる可能性があるので、サンプル スクリプトを共有していただけますか。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。
私がやっていること:
1. 2つの大きなデータテーブル(1つは10万行以上)をロードする
2. キーを一致させて結合する
3. すべてのフィルタ列から一意の値を抽出し、別のキャッシュテーブルに保存する
4. 複数のコンボボックスドロップダウン(合計13個のフィルター)を使用したカスタムUIの作成
5. キャッシュテーブルからコンボボックスの値を読み込む
6. ユーザーはドロップダウンから値を選択し、ボタンをクリックしてフィルタリングされたサブセットを作成します。
// This is simplified version:
Clear Log();
// Step 1-2: Load and join two tables
LoadAndJoinData = Function({},
dt_results = Data Table("Table1");
dt_tracker = Data Table("Table2");
// Join tables by matching key
dt_joined = dt_results << Join(
With(dt_tracker),
By Matching Columns(:key1 = :key2),
Drop multiples(0, 0),
Output Table("Joined_Data")
);
Return(dt_joined);
);
// Step 3: Create cache table with unique values - THIS IS SLOW
CreateFilterCache = Function({dt_source},
Print("Creating filter cache table...");
// Create cache table to store unique values
dt_cache = New Table("Filter_Cache",
New Column("Filter_Name", Character),
New Column("Filter_Value", Character)
);
column_list = {"Column1", "Column2", "Column3", "Column4", "Column5"};
current_row = 0;
For(i = 1, i <= N Items(column_list), i++,
col_name = column_list[i];
Print(" Processing: " || col_name);
// Extract unique values
col = Column(dt_source, col_name);
col_values = col << Get Values;
aa = Associative Array();
For(j = 1, j <= N Items(col_values), j++,
val = col_values[j];
If(!Is Missing(val) & val != "",
aa[val] = 1;
);
);
unique_list = aa << Get Keys;
unique_list = Sort Ascending(unique_list);
// Store in cache table
For(k = 1, k <= N Items(unique_list), k++,
current_row++;
dt_cache << Add Rows(1);
dt_cache:Filter_Name[current_row] = col_name;
dt_cache:Filter_Value[current_row] = unique_list[k];
);
);
Print("Cache table created with " || Char(N Rows(dt_cache)) || " entries");
Return(dt_cache);
);
// Step 5: Load unique values from cache table
GetValuesFromCache = Function({dt_cache, column_name},
value_list = {};
For(i = 1, i <= N Rows(dt_cache), i++,
If(dt_cache:Filter_Name[i] == column_name,
Insert Into(value_list, dt_cache:Filter_Value[i]);
);
);
Insert Into(value_list, "", 1);
Return(value_list);
);
// Step 4-5: Create filter window and load from cache
CreateFilterWindow = Function({dt_final, dt_cache},
Print("Loading dropdowns from cache...");
// Load from cache - STILL SLOW for large lists
unique_col1 = GetValuesFromCache(dt_cache, "Column1");
unique_col2 = GetValuesFromCache(dt_cache, "Column2");
unique_col3 = GetValuesFromCache(dt_cache, "Column3");
unique_col4 = GetValuesFromCache(dt_cache, "Column4");
unique_col5 = GetValuesFromCache(dt_cache, "Column5");
Print("Creating window...");
win = New Window("Custom Filter",
V List Box(
Panel Box("Select Filters",
V List Box(
H List Box(
Text Box("Filter 1:"),
cb_1 = Combo Box(unique_col1, "", <
<SET width="">
0, dt_subset = dt << Subset( Output Table Name("Filtered_" || Format(Today(), "yyyy-mm-dd")), Rows(rowList) ); Print("Subset created: " || Char(N Rows(dt_subset)) || " rows"); ); ) ) ); ); // Main execution dt_joined = LoadAndJoinData(); dt_cache = CreateFilterCache(dt_joined); // Create cache once CreateFilterWindow(dt_joined, dt_cache); // Use cached values
</SET>
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。要約テーブルの使用は、一意の値を取得するのに適した方法です。
Names Default To Here(1);
col_of_interest = "age";
dt = Open("$SAMPLE_DATA/Big Class.jmp");
dt_summary = dt << Summary(
Group(:age),
Freq("None"),
Weight("None"),
output table name("uniques"),
private
);
unique_ages = dt_summary[0, 1];
Close(dt_summary, no save);
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。ご提案ありがとうございます。確かにパフォーマンスは少し改善されましたが、ドロップダウンごとに固有のデータが多いため、ドロップダウンの表示速度はまだ遅いです。カスタムドロップダウンに良い解決策が見つからない場合は、データフィルターを使用してそこにボタンを追加する方法を見つける必要があるかもしれません。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。データ フィルターを使用して集計するのはいかがでしょうか?
Names Default to Here(1);
dt = Open( "$SAMPLE_DATA/Big Class Families.jmp" );
Tabulate(
Show Control Panel( 0 ),
Add Table( Row Table( Grouping Columns( :sex ) ), Row Table( Grouping Columns( :name ) ) ),
Local Data Filter( Mode( Show( 0 ) ), Add Filter( columns( :sex ), Where( :sex == "F" ) ) )
);
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。データフィルターをある程度操作することは可能ですが、すぐに限界に直面するでしょう。速度の問題がコンボボックス(の表示)内でない限り、最適化できる部分はまだまだたくさんあります。速度テストに使用できるサンプルテーブル(またはサンプルテーブル)を作成するスクリプトを提供していただければ、これらの最適化の可能性を示すのがはるかに容易になります。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。このテーブルにも数千の行があるため、おそらくこのスクリプトが役立つでしょう。
この部分を削除すると、コンボボックスの問題を確認できます。
// Truncate for testing purposes (Truncated it 50 rows this needs to be removed)
unique_flights = unique_flights[1 :: 50];
Show( N Items( unique_flights ) );
// ========================================
// TEST SCRIPT - Single Column Filter (Table Air Traffic)
// Column - Flight ID
// ========================================
Clear Log();
// Todo: The associative array is not an appropriate method for large datasets with many unique values.
// Perhaps use the summary table or something else. Or find unique column values using hashing and storing in a temp table.
// Open the Air Traffic sample data table
dt = Open( "$SAMPLE_DATA/Air Traffic.jmp" );
// Safety check
If( Is Empty( dt ),
Throw( "No data table is open. Please open a data table first." );
);
Print( "Current Data Table: " || (dt << Get Name) );
Print( "Rows: " || Char( N Rows( dt ) ) );
Print( "Columns: " || Char( N Cols( dt ) ) || "\n" );
// METHOD 1: Use Summary table (most efficient for large datasets)
dt_summary = dt << Summary(
Group( :Flight ID ),
Freq( "None" ),
Weight( "None" ),
output table name( "Temp Summary" ),
private
);
unique_flights = dt_summary:Flight ID << Get Values;
Close( dt_summary, No Save );
// Truncate for testing purposes (Truncated it 50 rows this needs to be removed)
unique_flights = unique_flights[1 :: 50];
Show( N Items( unique_flights ) );
// // Sort unique values for faster lookup
// unique_flights = Sort List( unique_flights );
// Store reference to data table
::testDataTable = dt;
// Create filter window
::testFilterWindow = New Window( "Test Filter",
V List Box(
Text Box( "Select Flight ID:" ),
cb_flight = Combo Box( unique_flights, "" ),
H List Box(
Button Box( "Create Filtered Table",
sel_flight = cb_flight << Get Selected;
Print( "\n" || Repeat( "=", 60 ) );
Print( "Button clicked!" );
Print( "Selected Flight ID: " || Char( sel_flight ) );
// Use Where to filter (faster than For Each Row)
If( sel_flight != "",
rowList = ::testDataTable << Get Rows Where( :Flight ID == sel_flight );
Print( "Total rows matching filter: " || Char( N Items( rowList ) ) );
If( N Items( rowList ) > 0,
dt_subset = ::testDataTable << Subset(
Output Table Name( "Test Filtered - " || Format( Today(), "yyyy-mm-dd h:m:s" ) ),
Rows( rowList )
);
Print( "\nSUCCESS: Filtered table created!" );
Print( "Table: " || (dt_subset << Get Name) );
Print( "Rows: " || Char( N Rows( dt_subset ) ) );
Print( Repeat( "=", 60 ) || "\n" );
dt_subset << Bring Window To Front;
Close( ::testFilterWindow );
,
Print( "ERROR: No rows match the selected filter" );
Print( Repeat( "=", 60 ) || "\n" );
);
);
),
Button Box( "Cancel",
Close( ::testFilterWindow );
)
)
)
);
私も同様の問題を抱えていたため、残念ながらデータ フィルターに切り替える必要がありました。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。コンボボックスが正常に動作したとしても、2万件ものエントリをスクロールするのはユーザーにとってかなり不快な体験になると思います。代わりに、例えば検索機能を追加したリストボックスを使うと、ユーザーエクスペリエンスが向上するかもしれません。JSLでテキストエディットボックスとリストボックスを組み合わせたり、データフィルターやフィルター列セレクターを使ったりすることも可能です。
Re: データをドロップダウンとして表示する最適な方法は? データ フィルターではありません。このスクリプトを共有していただきありがとうございます。まさにこのスクリプトは私が直面している問題を正確に描写しています。