cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
New to using JMP? Hit the ground running with the Early User Edition of Discovery Summit. Register now, free of charge.
Register for our Discovery Summit 2024 conference, Oct. 21-24, where you’ll learn, connect, and be inspired.
Choose Language Hide Translation Bar
STThunder
New Member

MakeRowStateHandler function: Exclude and Hide all but selected rows over different data table

Hi, 

 

I have to handle several Data Table and I would like to use only one filter. Ideally I would like to hide and exclude all the data that are not selected over different data table.

I used a modified version of a JSL code made my ian.cox@jmp.com, see below on JMP 17.0.0

 

// ian.cox@jmp.com: 03Nove2014

// Demo of how to link multiple child tables to a parent table using a row state handler

Names Default To Here( 1 );

// Make some tables to use

dt1 = New Table( "Table 1", 
New Column( "ID", Numeric, Conntinuous, Values( (1 :: 10)` ) ), 
New Column( "Response", Numeric, Continuous, Formula( Random Normal( 0, 1 ) ) )
);
dt1 << Set Name ("dt1 Master");

dt2 = New Table( "Table 2", 
New Column( "ID", Numeric, Conntinuous, Formula( Random Integer( 1, 5 ) ) ), 
New Column( "Attribute 2", Numeric, Continuous, Formula( Random Integer( 0, 10 ) ) ), 
AddRows( 20 )
);
dt2 << Set Name("dt2 - slave");

dt3 = New Table( "Table 3", 
New Column( "ID", Numeric, Conntinuous, Formula( Random Integer( 1, 11 ) ) ), 
New Column( "Attribute 3", Numeric, Continuous, Formula( Random Integer( 0, 100 ) ) ), 
AddRows( 30 )
);
dt3 << Set Name("dt3 - slave");
// Utility function:
// Given a data table, a column therein and some value(s) in that column, selects all corresponding rows.
// Need to allow for 'col' to be numeric (character), in which case 'vals' is a matrix (is a list).

selectMatchingRows = 

Function( {dt, col, vals}, 
rows2select = [];
If( Is Matrix( vals ), 
  // 'col' is numeric
For( i = 1, i <= N Row( vals ), i++, 
rows2select = V Concat( rows2select, dt << GetRowsWhere( col == vals[i] ) );
)
, 
  // 'col' is character
For( i = 1, i <= N Items( vals ), i++, 
rows2select = V Concat( rows2select, dt << GetRowsWhere( col == vals[i] ) );
)
);

dt << Select Rows( rows2select ) << Hide << Exclude;
/*
dt << Exclude;
dt << Hide;
*/
);

// Make a row state handler to be assigned to the 'master' table (dt1). Allow for multiple row selections.

propagateSelectionToOtherTables = 
Function( {x}, 
  // Get the rows that have been selected
selectedRows = dt1 << GetSelectedRows;
If( N Row( selectedRows ) > 0, 
  // Clear any existing selection
dt2 << ClearSelect;
dt3 << ClearSelect;
  // Get the corresponding IDs
IDs = dt1:ID[selectedRows];
  // Select the corresponding rows in dt2
selectMatchingRows( dt2, Expr( :ID ), IDs );
  // Select the corresponding rows in dt3
selectMatchingRows( dt3, Expr( :ID ), IDs );

);
);
// Assign the handler to dt1
rsh = dt1 << MakeRowStateHandler( propagateSelectionToOtherTables );

 

This code exclude the selected data at the very beginning (first selection in the master data table) but not afterward.

Are there any way to improve this code?

 

In advance thank you.

 

Antoine Carré

2 REPLIES 2
txnelson
Super User

Re: MakeRowStateHandler function: Exclude and Hide all but selected rows over different data table

I made some modifications to make the code work.  However, it isn't very robust code.

// ian.cox@jmp.com: 03Nove2014

// Demo of how to link multiple child tables to a parent table using a row state handler

Names Default To Here( 1 );

// Make some tables to use

dt1 = New Table( "Table 1",
	New Column( "ID", Numeric, Conntinuous, Values( (1 :: 10)` ) ),
	New Column( "Response", Numeric, Continuous, Formula( Random Normal( 0, 1 ) ) )
);
dt1 << Set Name( "dt1 Master" );

dt2 = New Table( "Table 2",
	New Column( "ID", Numeric, Conntinuous, Formula( Random Integer( 1, 5 ) ) ),
	New Column( "Attribute 2", Numeric, Continuous, Formula( Random Integer( 0, 10 ) ) ),
	AddRows( 20 )
);
dt2 << Set Name( "dt2 - slave" );

dt3 = New Table( "Table 3",
	New Column( "ID", Numeric, Conntinuous, Formula( Random Integer( 1, 11 ) ) ),
	New Column( "Attribute 3", Numeric, Continuous, Formula( Random Integer( 0, 100 ) ) ),
	AddRows( 30 )
);
dt3 << Set Name( "dt3 - slave" );
// Utility function:
// Given a data table, a column therein and some value(s) in that column, selects all corresponding rows.
// Need to allow for 'col' to be numeric (character), in which case 'vals' is a matrix (is a list).

selectMatchingRows = 

Function( {dt, col, vals},
	rows2select = [];
	If( Is Matrix( vals ), 
  // 'col' is numeric
		For( i = 1, i <= N Row( vals ), i++,
			rows2select = V Concat( rows2select, dt << GetRowsWhere( col == vals[i] ) )
		)
	, 
  // 'col' is character
		For( i = 1, i <= N Items( vals ), i++,
			rows2select = V Concat( rows2select, dt << GetRowsWhere( col == vals[i] ) )
		)
	);
	//dt << clear rowstates;
	dt << Select Rows( rows2select ) << Hide(1) << Exclude(1);
	dt << invert row selection;
	dt << Hide(0) << Exclude(0);
	dt << invert row selection;
/*
dt << Exclude;
dt << Hide;
*/
);

// Make a row state handler to be assigned to the 'master' table (dt1). Allow for multiple row selections.

propagateSelectionToOtherTables = Function( {x}, 
  // Get the rows that have been selected
	selectedRows = dt1 << GetSelectedRows;
	If( N Row( selectedRows ) > 0, 
  // Clear any existing selection
		dt2 << ClearSelect;
		dt3 << ClearSelect;
  // Get the corresponding IDs
		IDs = dt1:ID[selectedRows];
  // Select the corresponding rows in dt2
		selectMatchingRows( dt2, Expr( :ID ), IDs );
  // Select the corresponding rows in dt3
		selectMatchingRows( dt3, Expr( :ID ), IDs );
	,
		If( N Row( dt2 << get selected rows ) > 0,
			dt2 << Hide( 0 ) << exclude( 0 );
			dt2 << clear select;
		);
		If( N Row( dt3 << get selected rows ) > 0,
			dt3 << Hide( 0 ) << exclude( 0 );
			dt3 << clear select;
		);
	);
);
// Assign the handler to dt1
rsh = dt1 << MakeRowStateHandler( propagateSelectionToOtherTables );
Jim
jthi
Super User

Re: MakeRowStateHandler function: Exclude and Hide all but selected rows over different data table

Quite a few assumptions made but this might work

Names Default To Here(1);

dt1 = New Table("Table1",
	New Column("ID", Numeric, Ordinal, Values((1 :: 10)`)),
	New Column("Response", Numeric, Continuous, Formula(Random Normal(0, 1)))
);

dt2 = New Table("Table2",
	New Column("ID", Numeric, Ordinal, Formula(Random Integer(1, 5))),
	New Column("Attribute 2", Numeric, Ordinal, Formula(Random Integer(0, 10))),
	AddRows(20)
);

dt3 = New Table("Table3",
	New Column("ID", Numeric, Conntinuous, Formula(Random Integer(1, 11))),
	New Column("Attribute 3", Numeric, Continuous, Formula(Random Integer(0, 100))),
	AddRows(30)
);


set_states = function({dt, ids}, {Default Local},
	rows_to_show = dt << Get Rows Where(Contains(sel_ids, :ID));
	rstates = J(N Rows(dt), 1, 6); 
	rstates[rows_to_show] = 0;
	dt << Set Row States(rstates);	
);

Eval(EvalExpr(
	handler = Function({a},
		Try(
			sel_rows = Expr(dt1) << Get Selected Rows;
			sel_ids = Expr(dt1)[sel_rows, "ID"];
			set_states(Expr(dt2), sel_ids);
			set_states(Expr(dt3), sel_ids);
		,
			show(exception_msg);
		);
	);	
));

rsh = dt1 << Make Row State Handler(handler);

/*
nw = New Window("demo",
	H List Box(
		Panel Box("Table1 (parent table)",
			dt1 << new data box
		),
		V List Box(
			Panel Box("Table 2 (child table)",
				dt2 << new data box
			),
			Panel Box("Table 3 (child table)",
				dt3 << new data box
			)
		)
	)
);
*/

 

One thing to note: row states break very easily. Depending on what you are trying to do, you might want to use some other solution than row state handler

 

-Jarmo