cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
Voizingu
Level III

[JSL] Add more info to Columns in a List Box ()

Hello,

 

I am trying to display a New Window() to request the user to select some categorical factors from a data table in a List Box().

I would like to add more insight to this choice, by highlighting:

- the number of level for each factors

- a color to show the ratio of empty cells within each factors columns

see attached an example of what I would like to achieve.

 

In the following script, I calculate the info for each factor and populate a list "Value".

But then I don't know how to aproach the design of the List Box () with these infos

 

Thanks for your help

 

- voiz

image.png

 

Names Default To Here( 1 );
clear symbols();
Deletesymbols();

dt = New Table( "RawData",
	Add Rows( 20 ),
	New Column("factor1", Character, set values( {"A","A","A","A","A","A","A","B","B","B","B","B","B","C","C","C","C","C","C","C"})),
	New Column("factor2", Character, set values( {"T0","DROP1","DROP2","DROP3","DROP4","DROP5","DROP6","T0","DROP1","DROP2","DROP3","DROP4","DROP5","T0","DROP1","DROP2","DROP3","DROP4","DROP5", "DROP6"})),
	New Column("factor3", Character, set values({"1","1","1","2","2","", ,"","","" ,"" ,"", "","3","3","3","3"}) ),
	New Column("factor4", Character, set values({"a","a","a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b" , "b", "b", "b", "b"}) );
	);

RawDataCol = dt << get column names ("character");
show (RawDataCol);

for(i=1, i<= N items (RawDataCol), i++,
	FactorSummary = {};
	Eval(Eval Expr(FactorSummary = Column(dt, Expr(char(RawDataCol[i]))) << get values));
	//show (FactorSummary);
	
	//find cell count (non empty)
	Eval(Eval Expr(For( j = N Items(FactorSummary), j > 0, j--,
		If( FactorSummary[j] == "",
			Remove From( FactorSummary, j, 1 )
		)
	)));
	
	//Find number of level within a factor (non empty)
	Eval(Eval Expr(Summarize( LevelSummary = by(Column(dt, Expr(char(RawDataCol[i])))) )));
		Eval(Eval Expr(For( j = N Items(LevelSummary), j > 0, j--,
		If( LevelSummary[j] == "",
			Remove From( LevelSummary, j, 1 )
		)
	)));
	//show (LevelSummary);
	
	Eval(Eval Expr(Value = {Expr(RawDataCol[i]), Expr(N items(LevelSummary)), Expr(N items (FactorSummary) / N row(dt))}));
	show (Value);
);

MainWindow = New Window( "Select Factors",
	<<Modal,
	<<ReturnResult,
		V List Box(Align(center),
			Panel Box( "Select factors to run the analysis", 
				Lineup Box( N Col( 2 ), Spacing( 5 ), 
				PickData = List Box( RawDataCol ) ) )
));
1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

Re: [JSL] Add more info to Columns in a List Box ()

List Box isn't the most flexible display box and I agree with txnelson that that you could use Table Box. Below is one example

Names Default To Here(1);

dt = New Table("RawData",
	Add Rows(20),
	New Column("factor1",
		Character,
		set values({"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C"})
	),
	New Column("factor2",
		Character,
		set values(
			{"T0", "DROP1", "DROP2", "DROP3", "DROP4", "DROP5", "DROP6", "T0", "DROP1", "DROP2", "DROP3", "DROP4", "DROP5", "T0", "DROP1", "DROP2",
			"DROP3", "DROP4", "DROP5", "DROP6"}
		)
	),
	New Column("factor3", Character, set values({"1", "1", "1", "2", "2", "", , "", "", "", "", "", "", "3", "3", "3", "3"})),
	New Column("factor4", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"}))
);

cols = dt << get column names("character", "string");
factors = {};
factor_counts = {};
missing_perc = {};

For Each({colname}, cols,
	Summarize(dt, uniq = by(Eval(colname)));
	Remove From(uniq, Contains(uniq, ""));
	nvalues = Col Number(Column(dt, colname));
	Insert Into(factors, colname);
	Insert Into(factor_counts, N Items(uniq));
	Insert Into(missing_perc, (nvalues)/ N Rows(dt));
);

dt_factors = New Table("Demo",
	Add Rows(N Items(factors)),
	New Column("Factor", Character, Nominal, Values(factors)),
	New Column("Count", Numeric, Continuous, Values(factor_counts)),
	New Column("% Non-missing", Numeric, Continuous, Format("Percent", 12, 3), Values(missing_perc)),
	Invisible
);

orange_rows = dt_factors << Get Rows Where(:"% Non-missing"n < 0.5);
yellow_rows = dt_factors << Get Rows Where(0.5 < :"% Non-missing"n < 0.9);

For Each({colname}, dt_factors << Get Column Names("String"),
	Column(dt_factors, colname) << Color Cells("Green");
	Column(dt_factors, colname) << Color Cells("Orange", orange_rows);
	Column(dt_factors, colname) << Color Cells("Yellow", yellow_rows);
);

nw = New Window("Select",
	H List Box(
		Panel Box("Select factors to run the analysis",
			bb = dt_factors << get as report
		),
		Panel Box("Actions",
			Lineup Box(N Col(1),
				Button Box("OK",
					tb = bb << child;
					sel_rows = tb << get selected rows;
					show(sel_rows, tb[1][sel_rows]);
				),
				Button Box("Cancel", << Set Function(function({this}, this << close window))),
			)
		)
	)
);


Close(dt_factors, no save);

jthi_1-1726335238797.png

 

-Jarmo

View solution in original post

5 REPLIES 5
txnelson
Super User

Re: [JSL] Add more info to Columns in a List Box ()

I would change from using a list box to using a Table Box which will allow you to have multiple columns displayed

Using different colors for different rows will remain an issue, however you can easily add in a column that you can have that has 1, 2, etc "*" to indicate different levels.

Jim
jthi
Super User

Re: [JSL] Add more info to Columns in a List Box ()

List Box isn't the most flexible display box and I agree with txnelson that that you could use Table Box. Below is one example

Names Default To Here(1);

dt = New Table("RawData",
	Add Rows(20),
	New Column("factor1",
		Character,
		set values({"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C"})
	),
	New Column("factor2",
		Character,
		set values(
			{"T0", "DROP1", "DROP2", "DROP3", "DROP4", "DROP5", "DROP6", "T0", "DROP1", "DROP2", "DROP3", "DROP4", "DROP5", "T0", "DROP1", "DROP2",
			"DROP3", "DROP4", "DROP5", "DROP6"}
		)
	),
	New Column("factor3", Character, set values({"1", "1", "1", "2", "2", "", , "", "", "", "", "", "", "3", "3", "3", "3"})),
	New Column("factor4", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"}))
);

cols = dt << get column names("character", "string");
factors = {};
factor_counts = {};
missing_perc = {};

For Each({colname}, cols,
	Summarize(dt, uniq = by(Eval(colname)));
	Remove From(uniq, Contains(uniq, ""));
	nvalues = Col Number(Column(dt, colname));
	Insert Into(factors, colname);
	Insert Into(factor_counts, N Items(uniq));
	Insert Into(missing_perc, (nvalues)/ N Rows(dt));
);

dt_factors = New Table("Demo",
	Add Rows(N Items(factors)),
	New Column("Factor", Character, Nominal, Values(factors)),
	New Column("Count", Numeric, Continuous, Values(factor_counts)),
	New Column("% Non-missing", Numeric, Continuous, Format("Percent", 12, 3), Values(missing_perc)),
	Invisible
);

orange_rows = dt_factors << Get Rows Where(:"% Non-missing"n < 0.5);
yellow_rows = dt_factors << Get Rows Where(0.5 < :"% Non-missing"n < 0.9);

For Each({colname}, dt_factors << Get Column Names("String"),
	Column(dt_factors, colname) << Color Cells("Green");
	Column(dt_factors, colname) << Color Cells("Orange", orange_rows);
	Column(dt_factors, colname) << Color Cells("Yellow", yellow_rows);
);

nw = New Window("Select",
	H List Box(
		Panel Box("Select factors to run the analysis",
			bb = dt_factors << get as report
		),
		Panel Box("Actions",
			Lineup Box(N Col(1),
				Button Box("OK",
					tb = bb << child;
					sel_rows = tb << get selected rows;
					show(sel_rows, tb[1][sel_rows]);
				),
				Button Box("Cancel", << Set Function(function({this}, this << close window))),
			)
		)
	)
);


Close(dt_factors, no save);

jthi_1-1726335238797.png

 

-Jarmo
Voizingu
Level III

Re: [JSL] Add more info to Columns in a List Box ()

Hi Jarmo, 

 

I like this solution a lot (Thanks also Jim for the suggestion).

One thing I need to take in account is the fact that I might have multiple dozen of factors.
Is there a way to force a fixed height for Table Box() ?

For instance, only 5 visible row and the ability to scroll down to have a fixed height in order to add more user inputs (radio box, check box, etc...).

 

Below an example of Table Box () with more rows and all of them are visible (it will become an issue with much more factors)

 

Thanks a lot

 

image.png 

 

Names Default To Here(1);

dt = New Table("RawData",
	Add Rows(20),
	New Column("factor1",
		Character,
		set values({"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C"})
	),
	New Column("factor2",
		Character,
		set values(
			{"T0", "DROP1", "DROP2", "DROP3", "DROP4", "DROP5", "DROP6", "T0", "DROP1", "DROP2", "DROP3", "DROP4", "DROP5", "T0", "DROP1", "DROP2",
			"DROP3", "DROP4", "DROP5", "DROP6"}
		)
	),
	New Column("factor3", Character, set values({"1", "1", "1", "2", "2", "", , "", "", "", "", "", "", "3", "3", "3", "3"})),
	New Column("factor4", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor5", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor6", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor7", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor8", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor9", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor10", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor12", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor13", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factorA", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factorB", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factorB1", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factorC", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factorD", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor69", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor67", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor47", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"})),
	New Column("factor56", Character, set values({"a", "a", "a", "", "", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"}))
);

cols = dt << get column names("character", "string");
factors = {};
factor_counts = {};
missing_perc = {};

For Each({colname}, cols,
	Summarize(dt, uniq = by(Eval(colname)));
	Remove From(uniq, Contains(uniq, ""));
	nvalues = Col Number(Column(dt, colname));
	Insert Into(factors, colname);
	Insert Into(factor_counts, N Items(uniq));
	Insert Into(missing_perc, (nvalues)/ N Rows(dt));
);

dt_factors = New Table("Demo",
	Add Rows(N Items(factors)),
	New Column("Factor", Character, Nominal, Values(factors)),
	New Column("Count", Numeric, Continuous, Values(factor_counts)),
	New Column("% Non-missing", Numeric, Continuous, Format("Percent", 12, 3), Values(missing_perc)),
	Invisible
);

orange_rows = dt_factors << Get Rows Where(:"% Non-missing"n < 0.5);
yellow_rows = dt_factors << Get Rows Where(0.5 < :"% Non-missing"n < 0.9);

For Each({colname}, dt_factors << Get Column Names("String"),
	Column(dt_factors, colname) << Color Cells("Green");
	Column(dt_factors, colname) << Color Cells("Orange", orange_rows);
	Column(dt_factors, colname) << Color Cells("Yellow", yellow_rows);
);

nw = New Window("Select",
	H List Box(
		Panel Box("Select factors to run the analysis",
			bb = dt_factors << get as report
		),
		Panel Box("Actions",
			Lineup Box(N Col(1),
				Button Box("OK",
					tb = bb << child;
					sel_rows = tb << get selected rows;
					show(sel_rows, tb[1][sel_rows]);
				),
				Button Box("Cancel", << Set Function(function({this}, this << close window))),
			)
		)
	)
);


Close(dt_factors, no save);
txnelson
Super User

Re: [JSL] Add more info to Columns in a List Box ()

look in the scripting index and search on table box and you will see the examples on how to set the number of display lines

Jim
Voizingu
Level III

Re: [JSL] Add more info to Columns in a List Box ()

Hi Jim,

 

YES!, the command << set scrollable( 5, 0 ); solve my issue.

Thanks so much!!

 

Julien